mirror of
http://112.124.100.131/huang.ze/ebiz-dify-ai.git
synced 2025-12-09 10:56:52 +08:00
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:
@@ -31,8 +31,8 @@ export default function AccountAbout({
|
||||
className='!w-[480px] !max-w-[480px] !px-6 !py-4'
|
||||
>
|
||||
<div className='relative pt-4'>
|
||||
<div className='absolute -top-2 -right-4 flex justify-center items-center w-8 h-8 cursor-pointer' onClick={onCancel}>
|
||||
<RiCloseLine className='w-4 h-4 text-text-tertiary' />
|
||||
<div className='absolute -right-4 -top-2 flex h-8 w-8 cursor-pointer items-center justify-center' onClick={onCancel}>
|
||||
<RiCloseLine className='h-4 w-4 text-text-tertiary' />
|
||||
</div>
|
||||
<div>
|
||||
<LogoSite className='mx-auto mb-2' />
|
||||
@@ -51,8 +51,8 @@ export default function AccountAbout({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='mb-4 -mx-8 h-[0.5px] bg-divider-regular' />
|
||||
<div className='flex justify-between items-center'>
|
||||
<div className='-mx-8 mb-4 h-[0.5px] bg-divider-regular' />
|
||||
<div className='flex items-center justify-between'>
|
||||
<div className='text-xs font-medium text-text-primary'>
|
||||
{
|
||||
isLatest
|
||||
|
||||
@@ -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>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -34,16 +34,16 @@ export default function IntegrationsPage() {
|
||||
<div className={titleClassName}>{t('common.integrations.connected')}</div>
|
||||
{
|
||||
integrates.map(integrate => (
|
||||
<div key={integrate.provider} className='mb-2 flex items-center px-3 py-2 bg-gray-50 border-[0.5px] border-gray-200 rounded-lg'>
|
||||
<div key={integrate.provider} className='mb-2 flex items-center rounded-lg border-[0.5px] border-gray-200 bg-gray-50 px-3 py-2'>
|
||||
<div className={classNames('w-8 h-8 mr-3 bg-white rounded-lg border border-gray-100', s[`${integrate.provider}-icon`])} />
|
||||
<div className='grow'>
|
||||
<div className='leading-[21px] text-sm font-medium text-gray-800'>{integrateMap[integrate.provider].name}</div>
|
||||
<div className='leading-[18px] text-xs font-normal text-gray-500'>{integrateMap[integrate.provider].description}</div>
|
||||
<div className='text-sm font-medium leading-[21px] text-gray-800'>{integrateMap[integrate.provider].name}</div>
|
||||
<div className='text-xs font-normal leading-[18px] text-gray-500'>{integrateMap[integrate.provider].description}</div>
|
||||
</div>
|
||||
{
|
||||
!integrate.is_bound && (
|
||||
<Link
|
||||
className='flex items-center h-8 px-[7px] bg-white rounded-lg border border-gray-200 text-xs font-medium text-gray-700 cursor-pointer'
|
||||
className='flex h-8 cursor-pointer items-center rounded-lg border border-gray-200 bg-white px-[7px] text-xs font-medium text-gray-700'
|
||||
href={integrate.link}
|
||||
target='_blank' rel='noopener noreferrer'>
|
||||
{t('common.integrations.connect')}
|
||||
|
||||
@@ -8,18 +8,18 @@ const Empty = () => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div className='mb-2 p-6 rounded-xl bg-background-section'>
|
||||
<div className='flex items-center justify-center mb-3 w-10 h-10 rounded-[10px] bg-components-card-bg-alt backdrop-blur-sm border-[0.5px] border-components-card-border shadow-lg'>
|
||||
<RiPuzzle2Line className='w-5 h-5 text-text-accent' />
|
||||
<div className='mb-2 rounded-xl bg-background-section p-6'>
|
||||
<div className='mb-3 flex h-10 w-10 items-center justify-center rounded-[10px] border-[0.5px] border-components-card-border bg-components-card-bg-alt shadow-lg backdrop-blur-sm'>
|
||||
<RiPuzzle2Line className='h-5 w-5 text-text-accent' />
|
||||
</div>
|
||||
<div className='mb-1 text-text-secondary system-sm-medium'>{t('common.apiBasedExtension.title')}</div>
|
||||
<div className='system-sm-medium mb-1 text-text-secondary'>{t('common.apiBasedExtension.title')}</div>
|
||||
<a
|
||||
className='flex items-center system-xs-regular text-text-accent'
|
||||
className='system-xs-regular flex items-center text-text-accent'
|
||||
href={t('common.apiBasedExtension.linkUrl') || '/'}
|
||||
target='_blank' rel='noopener noreferrer'
|
||||
>
|
||||
{t('common.apiBasedExtension.link')}
|
||||
<RiExternalLinkLine className='ml-1 w-3 h-3' />
|
||||
<RiExternalLinkLine className='ml-1 h-3 w-3' />
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -47,7 +47,7 @@ const ApiBasedExtensionPage = () => {
|
||||
className='w-full'
|
||||
onClick={handleOpenApiBasedExtensionModal}
|
||||
>
|
||||
<RiAddLine className='mr-1 w-4 h-4' />
|
||||
<RiAddLine className='mr-1 h-4 w-4' />
|
||||
{t('common.apiBasedExtension.add')}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -37,23 +37,23 @@ const Item: FC<ItemProps> = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='group flex items-center mb-2 px-4 py-2 border-[0.5px] border-transparent rounded-xl bg-components-input-bg-normal hover:border-components-input-border-active hover:shadow-xs'>
|
||||
<div className='group mb-2 flex items-center rounded-xl border-[0.5px] border-transparent bg-components-input-bg-normal px-4 py-2 hover:border-components-input-border-active hover:shadow-xs'>
|
||||
<div className='grow'>
|
||||
<div className='mb-0.5 text-[13px] font-medium text-text-secondary'>{data.name}</div>
|
||||
<div className='text-xs text-text-tertiary'>{data.api_endpoint}</div>
|
||||
</div>
|
||||
<div className='hidden group-hover:flex items-center'>
|
||||
<div className='hidden items-center group-hover:flex'>
|
||||
<Button
|
||||
className='mr-1'
|
||||
onClick={handleOpenApiBasedExtensionModal}
|
||||
>
|
||||
<RiEditLine className='mr-1 w-4 h-4' />
|
||||
<RiEditLine className='mr-1 h-4 w-4' />
|
||||
{t('common.operation.edit')}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => setShowDeleteConfirm(true)}
|
||||
>
|
||||
<RiDeleteBinLine className='mr-1 w-4 h-4' />
|
||||
<RiDeleteBinLine className='mr-1 h-4 w-4' />
|
||||
{t('common.operation.delete')}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -75,7 +75,7 @@ const ApiBasedExtensionModal: FC<ApiBasedExtensionModalProps> = ({
|
||||
<Modal
|
||||
isShow
|
||||
onClose={() => { }}
|
||||
className='!p-8 !pb-6 !max-w-none !w-[640px]'
|
||||
className='!w-[640px] !max-w-none !p-8 !pb-6'
|
||||
>
|
||||
<div className='mb-2 text-xl font-semibold text-text-primary'>
|
||||
{
|
||||
@@ -85,49 +85,49 @@ const ApiBasedExtensionModal: FC<ApiBasedExtensionModalProps> = ({
|
||||
}
|
||||
</div>
|
||||
<div className='py-2'>
|
||||
<div className='leading-9 text-sm font-medium text-text-primary'>
|
||||
<div className='text-sm font-medium leading-9 text-text-primary'>
|
||||
{t('common.apiBasedExtension.modal.name.title')}
|
||||
</div>
|
||||
<input
|
||||
value={localeData.name || ''}
|
||||
onChange={e => handleDataChange('name', e.target.value)}
|
||||
className='block px-3 w-full h-9 bg-components-input-bg-normal rounded-lg text-sm text-text-primary outline-none appearance-none'
|
||||
className='block h-9 w-full appearance-none rounded-lg bg-components-input-bg-normal px-3 text-sm text-text-primary outline-none'
|
||||
placeholder={t('common.apiBasedExtension.modal.name.placeholder') || ''}
|
||||
/>
|
||||
</div>
|
||||
<div className='py-2'>
|
||||
<div className='flex justify-between items-center h-9 text-sm font-medium text-text-primary'>
|
||||
<div className='flex h-9 items-center justify-between text-sm font-medium text-text-primary'>
|
||||
{t('common.apiBasedExtension.modal.apiEndpoint.title')}
|
||||
<a
|
||||
href={t('common.apiBasedExtension.linkUrl') || '/'}
|
||||
target='_blank' rel='noopener noreferrer'
|
||||
className='group flex items-center text-xs text-text-accent font-normal'
|
||||
className='group flex items-center text-xs font-normal text-text-accent'
|
||||
>
|
||||
<BookOpen01 className='mr-1 w-3 h-3' />
|
||||
<BookOpen01 className='mr-1 h-3 w-3' />
|
||||
{t('common.apiBasedExtension.link')}
|
||||
</a>
|
||||
</div>
|
||||
<input
|
||||
value={localeData.api_endpoint || ''}
|
||||
onChange={e => handleDataChange('api_endpoint', e.target.value)}
|
||||
className='block px-3 w-full h-9 bg-components-input-bg-normal rounded-lg text-sm text-text-primary outline-none appearance-none'
|
||||
className='block h-9 w-full appearance-none rounded-lg bg-components-input-bg-normal px-3 text-sm text-text-primary outline-none'
|
||||
placeholder={t('common.apiBasedExtension.modal.apiEndpoint.placeholder') || ''}
|
||||
/>
|
||||
</div>
|
||||
<div className='py-2'>
|
||||
<div className='leading-9 text-sm font-medium text-text-primary'>
|
||||
<div className='text-sm font-medium leading-9 text-text-primary'>
|
||||
{t('common.apiBasedExtension.modal.apiKey.title')}
|
||||
</div>
|
||||
<div className='flex items-center'>
|
||||
<input
|
||||
value={localeData.api_key || ''}
|
||||
onChange={e => handleDataChange('api_key', e.target.value)}
|
||||
className='block grow mr-2 px-3 h-9 bg-components-input-bg-normal rounded-lg text-sm text-text-primary outline-none appearance-none'
|
||||
className='mr-2 block h-9 grow appearance-none rounded-lg bg-components-input-bg-normal px-3 text-sm text-text-primary outline-none'
|
||||
placeholder={t('common.apiBasedExtension.modal.apiKey.placeholder') || ''}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex items-center justify-end mt-6'>
|
||||
<div className='mt-6 flex items-center justify-end'>
|
||||
<Button
|
||||
onClick={onCancel}
|
||||
className='mr-2'
|
||||
|
||||
@@ -54,40 +54,40 @@ const ApiBasedExtensionSelector: FC<ApiBasedExtensionSelectorProps> = ({
|
||||
{
|
||||
currentItem
|
||||
? (
|
||||
<div className='flex items-center justify-between pl-3 pr-2.5 h-9 bg-components-input-bg-normal rounded-lg cursor-pointer'>
|
||||
<div className='flex h-9 cursor-pointer items-center justify-between rounded-lg bg-components-input-bg-normal pl-3 pr-2.5'>
|
||||
<div className='text-sm text-text-primary'>{currentItem.name}</div>
|
||||
<div className='flex items-center'>
|
||||
<div className='mr-1.5 w-[270px] text-xs text-text-quaternary truncate text-right'>
|
||||
<div className='mr-1.5 w-[270px] truncate text-right text-xs text-text-quaternary'>
|
||||
{currentItem.api_endpoint}
|
||||
</div>
|
||||
<RiArrowDownSLine className={`w-4 h-4 text-text-secondary ${!open && 'opacity-60'}`} />
|
||||
<RiArrowDownSLine className={`h-4 w-4 text-text-secondary ${!open && 'opacity-60'}`} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
: (
|
||||
<div className='flex items-center justify-between pl-3 pr-2.5 h-9 bg-components-input-bg-normal rounded-lg text-sm text-text-quaternary cursor-pointer'>
|
||||
<div className='flex h-9 cursor-pointer items-center justify-between rounded-lg bg-components-input-bg-normal pl-3 pr-2.5 text-sm text-text-quaternary'>
|
||||
{t('common.apiBasedExtension.selector.placeholder')}
|
||||
<RiArrowDownSLine className={`w-4 h-4 text-text-secondary ${!open && 'opacity-60'}`} />
|
||||
<RiArrowDownSLine className={`h-4 w-4 text-text-secondary ${!open && 'opacity-60'}`} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</PortalToFollowElemTrigger>
|
||||
<PortalToFollowElemContent className='w-[calc(100%-32px)] max-w-[576px] z-[102]'>
|
||||
<div className='w-full rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg z-10'>
|
||||
<PortalToFollowElemContent className='z-[102] w-[calc(100%-32px)] max-w-[576px]'>
|
||||
<div className='z-10 w-full rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg'>
|
||||
<div className='p-1'>
|
||||
<div className='flex items-center justify-between px-3 pt-2 pb-1'>
|
||||
<div className='flex items-center justify-between px-3 pb-1 pt-2'>
|
||||
<div className='text-xs font-medium text-text-tertiary'>
|
||||
{t('common.apiBasedExtension.selector.title')}
|
||||
</div>
|
||||
<div
|
||||
className='flex items-center text-xs text-text-accent cursor-pointer'
|
||||
className='flex cursor-pointer items-center text-xs text-text-accent'
|
||||
onClick={() => {
|
||||
setOpen(false)
|
||||
setShowAccountSettingModal({ payload: 'api-based-extension' })
|
||||
}}
|
||||
>
|
||||
{t('common.apiBasedExtension.selector.manage')}
|
||||
<ArrowUpRight className='ml-0.5 w-3 h-3' />
|
||||
<ArrowUpRight className='ml-0.5 h-3 w-3' />
|
||||
</div>
|
||||
</div>
|
||||
<div className='max-h-[250px] overflow-y-auto'>
|
||||
@@ -95,7 +95,7 @@ const ApiBasedExtensionSelector: FC<ApiBasedExtensionSelectorProps> = ({
|
||||
data?.map(item => (
|
||||
<div
|
||||
key={item.id}
|
||||
className='px-3 py-1.5 w-full cursor-pointer hover:stroke-state-base-hover rounded-md text-left'
|
||||
className='w-full cursor-pointer rounded-md px-3 py-1.5 text-left hover:stroke-state-base-hover'
|
||||
onClick={() => handleSelect(item.id!)}
|
||||
>
|
||||
<div className='text-sm text-text-primary'>{item.name}</div>
|
||||
@@ -108,13 +108,13 @@ const ApiBasedExtensionSelector: FC<ApiBasedExtensionSelectorProps> = ({
|
||||
<div className='h-[1px] bg-divider-regular' />
|
||||
<div className='p-1'>
|
||||
<div
|
||||
className='flex items-center px-3 h-8 text-sm text-text-accent cursor-pointer'
|
||||
className='flex h-8 cursor-pointer items-center px-3 text-sm text-text-accent'
|
||||
onClick={() => {
|
||||
setOpen(false)
|
||||
setShowApiBasedExtensionModal({ payload: {}, onSaveCallback: () => mutate() })
|
||||
}}
|
||||
>
|
||||
<RiAddLine className='mr-2 w-4 h-4' />
|
||||
<RiAddLine className='mr-2 h-4 w-4' />
|
||||
{t('common.operation.add')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -26,17 +26,17 @@ const Collapse = ({
|
||||
|
||||
return (
|
||||
<div className={classNames('bg-background-section-burn rounded-xl', wrapperClassName)}>
|
||||
<div className='flex items-center justify-between leading-[18px] px-3 py-2 text-xs font-medium text-text-secondary cursor-pointer' onClick={toggle}>
|
||||
<div className='flex cursor-pointer items-center justify-between px-3 py-2 text-xs font-medium leading-[18px] text-text-secondary' onClick={toggle}>
|
||||
{title}
|
||||
{
|
||||
open
|
||||
? <ChevronDownIcon className='w-3 h-3 text-components-button-tertiary-text' />
|
||||
: <ChevronRightIcon className='w-3 h-3 text-components-button-tertiary-text' />
|
||||
? <ChevronDownIcon className='h-3 w-3 text-components-button-tertiary-text' />
|
||||
: <ChevronRightIcon className='h-3 w-3 text-components-button-tertiary-text' />
|
||||
}
|
||||
</div>
|
||||
{
|
||||
open && (
|
||||
<div className='py-1 mb-1 mx-1 border-t border-divider-subtle rounded-lg bg-components-panel-on-panel-item-bg'>
|
||||
<div className='mx-1 mb-1 rounded-lg border-t border-divider-subtle bg-components-panel-on-panel-item-bg py-1'>
|
||||
{
|
||||
items.map(item => (
|
||||
<div key={item.key} onClick={() => onSelect && onSelect(item)}>
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
RiMoreFill,
|
||||
RiStickyNoteAddLine,
|
||||
} from '@remixicon/react'
|
||||
import { Menu, Transition } from '@headlessui/react'
|
||||
import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react'
|
||||
import { syncDataSourceNotion, updateDataSourceNotionAction } from '@/service/common'
|
||||
import Toast from '@/app/components/base/toast'
|
||||
import cn from '@/utils/classnames'
|
||||
@@ -48,9 +48,9 @@ export default function Operate({
|
||||
{
|
||||
({ open }) => (
|
||||
<>
|
||||
<Menu.Button className={cn('flex items-center justify-center w-8 h-8 rounded-lg hover:bg-state-base-hover', open && 'bg-state-base-hover')}>
|
||||
<RiMoreFill className='w-4 h-4 text-text-secondary' />
|
||||
</Menu.Button>
|
||||
<MenuButton className={cn('flex h-8 w-8 items-center justify-center rounded-lg hover:bg-state-base-hover', open && 'bg-state-base-hover')}>
|
||||
<RiMoreFill className='h-4 w-4 text-text-secondary' />
|
||||
</MenuButton>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
enter="transition ease-out duration-100"
|
||||
@@ -60,38 +60,38 @@ export default function Operate({
|
||||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<Menu.Items className="absolute right-0 top-9 w-60 max-w-80 origin-top-right rounded-xl bg-components-panel-bg-blur backdrop-blur-sm border-[0.5px] border-components-panel-border shadow-lg">
|
||||
<MenuItems className="absolute right-0 top-9 w-60 max-w-80 origin-top-right rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg backdrop-blur-sm">
|
||||
<div className="px-1 py-1">
|
||||
<Menu.Item>
|
||||
<MenuItem>
|
||||
<div
|
||||
className='flex px-3 py-2 hover:bg-state-base-hover rounded-lg cursor-pointer'
|
||||
className='flex cursor-pointer rounded-lg px-3 py-2 hover:bg-state-base-hover'
|
||||
onClick={onAuthAgain}
|
||||
>
|
||||
<RiStickyNoteAddLine className='mr-2 mt-[2px] w-4 h-4 text-text-tertiary' />
|
||||
<RiStickyNoteAddLine className='mr-2 mt-[2px] h-4 w-4 text-text-tertiary' />
|
||||
<div>
|
||||
<div className='system-sm-semibold text-text-secondary'>{t('common.dataSource.notion.changeAuthorizedPages')}</div>
|
||||
<div className='text-text-tertiary system-xs-regular'>
|
||||
<div className='system-xs-regular text-text-tertiary'>
|
||||
{payload.total} {t('common.dataSource.notion.pagesAuthorized')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
<div className='flex px-3 py-2 hover:bg-state-base-hover rounded-lg cursor-pointer' onClick={handleSync}>
|
||||
<RiLoopLeftLine className='mr-2 mt-[2px] w-4 h-4 text-text-tertiary' />
|
||||
</MenuItem>
|
||||
<MenuItem>
|
||||
<div className='flex cursor-pointer rounded-lg px-3 py-2 hover:bg-state-base-hover' onClick={handleSync}>
|
||||
<RiLoopLeftLine className='mr-2 mt-[2px] h-4 w-4 text-text-tertiary' />
|
||||
<div className='system-sm-semibold text-text-secondary'>{t('common.dataSource.notion.sync')}</div>
|
||||
</div>
|
||||
</Menu.Item>
|
||||
</MenuItem>
|
||||
</div>
|
||||
<Menu.Item>
|
||||
<div className='p-1 border-t border-divider-subtle'>
|
||||
<div className='flex px-3 py-2 hover:bg-state-base-hover rounded-lg cursor-pointer' onClick={handleRemove}>
|
||||
<RiDeleteBinLine className='mr-2 mt-[2px] w-4 h-4 text-text-tertiary' />
|
||||
<MenuItem>
|
||||
<div className='border-t border-divider-subtle p-1'>
|
||||
<div className='flex cursor-pointer rounded-lg px-3 py-2 hover:bg-state-base-hover' onClick={handleRemove}>
|
||||
<RiDeleteBinLine className='mr-2 mt-[2px] h-4 w-4 text-text-tertiary' />
|
||||
<div className='system-sm-semibold text-text-secondary'>{t('common.dataSource.notion.remove')}</div>
|
||||
</div>
|
||||
</div>
|
||||
</Menu.Item>
|
||||
</Menu.Items>
|
||||
</MenuItem>
|
||||
</MenuItems>
|
||||
</Transition>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -88,11 +88,11 @@ const ConfigFirecrawlModal: FC<Props> = ({
|
||||
|
||||
return (
|
||||
<PortalToFollowElem open>
|
||||
<PortalToFollowElemContent className='w-full h-full z-[60]'>
|
||||
<PortalToFollowElemContent className='z-[60] h-full w-full'>
|
||||
<div className='fixed inset-0 flex items-center justify-center bg-background-overlay'>
|
||||
<div className='mx-2 w-[640px] max-h-[calc(100vh-120px)] bg-components-panel-bg shadow-xl rounded-2xl overflow-y-auto'>
|
||||
<div className='mx-2 max-h-[calc(100vh-120px)] w-[640px] overflow-y-auto rounded-2xl bg-components-panel-bg shadow-xl'>
|
||||
<div className='px-8 pt-8'>
|
||||
<div className='flex justify-between items-center mb-4'>
|
||||
<div className='mb-4 flex items-center justify-between'>
|
||||
<div className='system-xl-semibold text-text-primary'>{t(`${I18N_PREFIX}.configFirecrawl`)}</div>
|
||||
</div>
|
||||
|
||||
@@ -113,10 +113,10 @@ const ConfigFirecrawlModal: FC<Props> = ({
|
||||
placeholder={DEFAULT_BASE_URL}
|
||||
/>
|
||||
</div>
|
||||
<div className='my-8 flex justify-between items-center h-8'>
|
||||
<a className='flex items-center space-x-1 leading-[18px] text-xs font-normal text-text-accent' target='_blank' href='https://www.firecrawl.dev/account'>
|
||||
<div className='my-8 flex h-8 items-center justify-between'>
|
||||
<a className='flex items-center space-x-1 text-xs font-normal leading-[18px] text-text-accent' target='_blank' href='https://www.firecrawl.dev/account'>
|
||||
<span>{t(`${I18N_PREFIX}.getApiKeyLinkText`)}</span>
|
||||
<LinkExternal02 className='w-3 h-3' />
|
||||
<LinkExternal02 className='h-3 w-3' />
|
||||
</a>
|
||||
<div className='flex'>
|
||||
<Button
|
||||
@@ -139,11 +139,11 @@ const ConfigFirecrawlModal: FC<Props> = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className='border-t-[0.5px] border-t-divider-regular'>
|
||||
<div className='flex justify-center items-center py-3 bg-background-section-burn text-xs text-text-tertiary'>
|
||||
<Lock01 className='mr-1 w-3 h-3 text-text-tertiary' />
|
||||
<div className='flex items-center justify-center bg-background-section-burn py-3 text-xs text-text-tertiary'>
|
||||
<Lock01 className='mr-1 h-3 w-3 text-text-tertiary' />
|
||||
{t('common.modelProvider.encrypted.front')}
|
||||
<a
|
||||
className='text-text-accent mx-1'
|
||||
className='mx-1 text-text-accent'
|
||||
target='_blank' rel='noopener noreferrer'
|
||||
href='https://pycryptodome.readthedocs.io/en/latest/src/cipher/oaep.html'
|
||||
>
|
||||
|
||||
@@ -74,11 +74,11 @@ const ConfigJinaReaderModal: FC<Props> = ({
|
||||
|
||||
return (
|
||||
<PortalToFollowElem open>
|
||||
<PortalToFollowElemContent className='w-full h-full z-[60]'>
|
||||
<PortalToFollowElemContent className='z-[60] h-full w-full'>
|
||||
<div className='fixed inset-0 flex items-center justify-center bg-background-overlay'>
|
||||
<div className='mx-2 w-[640px] max-h-[calc(100vh-120px)] bg-components-panel-bg shadow-xl rounded-2xl overflow-y-auto'>
|
||||
<div className='mx-2 max-h-[calc(100vh-120px)] w-[640px] overflow-y-auto rounded-2xl bg-components-panel-bg shadow-xl'>
|
||||
<div className='px-8 pt-8'>
|
||||
<div className='flex justify-between items-center mb-4'>
|
||||
<div className='mb-4 flex items-center justify-between'>
|
||||
<div className='system-xl-semibold text-text-primary'>{t(`${I18N_PREFIX}.configJinaReader`)}</div>
|
||||
</div>
|
||||
|
||||
@@ -92,10 +92,10 @@ const ConfigJinaReaderModal: FC<Props> = ({
|
||||
placeholder={t(`${I18N_PREFIX}.apiKeyPlaceholder`)!}
|
||||
/>
|
||||
</div>
|
||||
<div className='my-8 flex justify-between items-center h-8'>
|
||||
<a className='flex items-center space-x-1 leading-[18px] text-xs font-normal text-text-accent' target='_blank' href='https://jina.ai/reader/'>
|
||||
<div className='my-8 flex h-8 items-center justify-between'>
|
||||
<a className='flex items-center space-x-1 text-xs font-normal leading-[18px] text-text-accent' target='_blank' href='https://jina.ai/reader/'>
|
||||
<span>{t(`${I18N_PREFIX}.getApiKeyLinkText`)}</span>
|
||||
<LinkExternal02 className='w-3 h-3' />
|
||||
<LinkExternal02 className='h-3 w-3' />
|
||||
</a>
|
||||
<div className='flex'>
|
||||
<Button
|
||||
@@ -118,11 +118,11 @@ const ConfigJinaReaderModal: FC<Props> = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className='border-t-[0.5px] border-t-divider-regular'>
|
||||
<div className='flex justify-center items-center py-3 bg-background-section-burn text-xs text-text-tertiary'>
|
||||
<Lock01 className='mr-1 w-3 h-3 text-text-tertiary' />
|
||||
<div className='flex items-center justify-center bg-background-section-burn py-3 text-xs text-text-tertiary'>
|
||||
<Lock01 className='mr-1 h-3 w-3 text-text-tertiary' />
|
||||
{t('common.modelProvider.encrypted.front')}
|
||||
<a
|
||||
className='text-text-accent mx-1'
|
||||
className='mx-1 text-text-accent'
|
||||
target='_blank' rel='noopener noreferrer'
|
||||
href='https://pycryptodome.readthedocs.io/en/latest/src/cipher/oaep.html'
|
||||
>
|
||||
|
||||
@@ -85,10 +85,10 @@ const DataSourceWebsite: FC<Props> = ({ provider }) => {
|
||||
logo: ({ className }: { className: string }) => (
|
||||
item.provider === DataSourceProvider.fireCrawl
|
||||
? (
|
||||
<div className={cn(className, 'flex items-center justify-center w-5 h-5 !bg-background-default border border-divider-subtle text-xs font-medium text-text-tertiary rounded ml-3')}>🔥</div>
|
||||
<div className={cn(className, 'ml-3 flex h-5 w-5 items-center justify-center rounded border border-divider-subtle !bg-background-default text-xs font-medium text-text-tertiary')}>🔥</div>
|
||||
)
|
||||
: (
|
||||
<div className={cn(className, 'flex items-center justify-center w-5 h-5 !bg-background-default border border-divider-subtle text-xs font-medium text-text-tertiary rounded ml-3')}>
|
||||
<div className={cn(className, 'ml-3 flex h-5 w-5 items-center justify-center rounded border border-divider-subtle !bg-background-default text-xs font-medium text-text-tertiary')}>
|
||||
<span className={s.jinaLogo} />
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -44,22 +44,22 @@ const ConfigItem: FC<Props> = ({
|
||||
const onChangeAuthorizedPage = notionActions?.onChangeAuthorizedPage || function () { }
|
||||
|
||||
return (
|
||||
<div className={cn(s['workspace-item'], 'flex items-center mb-1 py-1 pr-1 bg-components-panel-on-panel-item-bg rounded-lg')} key={payload.id}>
|
||||
<div className={cn(s['workspace-item'], 'mb-1 flex items-center rounded-lg bg-components-panel-on-panel-item-bg py-1 pr-1')} key={payload.id}>
|
||||
<payload.logo className='ml-3 mr-1.5' />
|
||||
<div className='grow py-[7px] system-sm-medium text-text-secondary truncate' title={payload.name}>{payload.name}</div>
|
||||
<div className='system-sm-medium grow truncate py-[7px] text-text-secondary' title={payload.name}>{payload.name}</div>
|
||||
{
|
||||
payload.isActive
|
||||
? <Indicator className='shrink-0 mr-[6px]' color='green' />
|
||||
: <Indicator className='shrink-0 mr-[6px]' color='yellow' />
|
||||
? <Indicator className='mr-[6px] shrink-0' color='green' />
|
||||
: <Indicator className='mr-[6px] shrink-0' color='yellow' />
|
||||
}
|
||||
<div className={`shrink-0 mr-3 system-xs-semibold-uppercase ${payload.isActive ? 'text-util-colors-green-green-600' : 'text-util-colors-warning-warning-600'}`}>
|
||||
<div className={`system-xs-semibold-uppercase mr-3 shrink-0 ${payload.isActive ? 'text-util-colors-green-green-600' : 'text-util-colors-warning-warning-600'}`}>
|
||||
{
|
||||
payload.isActive
|
||||
? t(isNotion ? 'common.dataSource.notion.connected' : 'common.dataSource.website.active')
|
||||
: t(isNotion ? 'common.dataSource.notion.disconnected' : 'common.dataSource.website.inactive')
|
||||
}
|
||||
</div>
|
||||
<div className='mr-2 w-[1px] h-3 bg-divider-regular' />
|
||||
<div className='mr-2 h-3 w-[1px] bg-divider-regular' />
|
||||
{isNotion && (
|
||||
<Operate payload={{
|
||||
id: payload.id,
|
||||
@@ -70,8 +70,8 @@ const ConfigItem: FC<Props> = ({
|
||||
|
||||
{
|
||||
isWebsite && !readOnly && (
|
||||
<div className='p-2 text-text-tertiary cursor-pointer rounded-md hover:bg-state-base-hover' onClick={onRemove} >
|
||||
<RiDeleteBinLine className='w-4 h-4' />
|
||||
<div className='cursor-pointer rounded-md p-2 text-text-tertiary hover:bg-state-base-hover' onClick={onRemove} >
|
||||
<RiDeleteBinLine className='h-4 w-4' />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -42,14 +42,14 @@ const Panel: FC<Props> = ({
|
||||
const isWebsite = type === DataSourceType.website
|
||||
|
||||
return (
|
||||
<div className='mb-2 bg-background-section-burn rounded-xl'>
|
||||
<div className='mb-2 rounded-xl bg-background-section-burn'>
|
||||
<div className='flex items-center px-3 py-[9px]'>
|
||||
<div className={cn(s[`${type}-icon`], 'w-8 h-8 mr-3 border border-divider-subtle rounded-lg !bg-background-default')} />
|
||||
<div className={cn(s[`${type}-icon`], 'mr-3 h-8 w-8 rounded-lg border border-divider-subtle !bg-background-default')} />
|
||||
<div className='grow'>
|
||||
<div className='flex items-center h-5'>
|
||||
<div className='flex h-5 items-center'>
|
||||
<div className='text-sm font-medium text-text-primary'>{t(`common.dataSource.${type}.title`)}</div>
|
||||
{isWebsite && (
|
||||
<div className='ml-1 leading-[18px] px-1.5 rounded-md bg-components-badge-white-to-dark text-xs font-medium text-text-secondary'>
|
||||
<div className='ml-1 rounded-md bg-components-badge-white-to-dark px-1.5 text-xs font-medium leading-[18px] text-text-secondary'>
|
||||
<span className='text-text-tertiary'>{t('common.dataSource.website.with')}</span> { provider === DataSourceProvider.fireCrawl ? '🔥 Firecrawl' : 'Jina Reader'}
|
||||
</div>
|
||||
)}
|
||||
@@ -79,12 +79,12 @@ const Panel: FC<Props> = ({
|
||||
<>
|
||||
{isSupportList && <div
|
||||
className={
|
||||
`flex items-center px-3 py-1 min-h-7 bg-components-button-secondary-bg border-[0.5px] border-components-button-secondary-border system-sm-medium text-components-button-secondary-accent-text rounded-md
|
||||
${!readOnly ? 'cursor-pointer' : 'grayscale opacity-50 cursor-default'}`
|
||||
`system-sm-medium flex min-h-7 items-center rounded-md border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg px-3 py-1 text-components-button-secondary-accent-text
|
||||
${!readOnly ? 'cursor-pointer' : 'cursor-default opacity-50 grayscale'}`
|
||||
}
|
||||
onClick={onConfigure}
|
||||
>
|
||||
<RiAddLine className='w-4 h-4 text-components-button-secondary-accent-text mr-[5px]' />
|
||||
<RiAddLine className='mr-[5px] h-4 w-4 text-components-button-secondary-accent-text' />
|
||||
{t('common.dataSource.connect')}
|
||||
</div>}
|
||||
</>
|
||||
@@ -96,9 +96,9 @@ const Panel: FC<Props> = ({
|
||||
{isWebsite && !isConfigured && (
|
||||
<div
|
||||
className={
|
||||
`flex items-center ml-3 px-3 h-7 bg-components-button-secondary-bg border-[0.5px] border-components-button-secondary-border
|
||||
rounded-md text-xs font-medium text-components-button-secondary-accent-text
|
||||
${!readOnly ? 'cursor-pointer' : 'grayscale opacity-50 cursor-default'}`
|
||||
`ml-3 flex h-7 items-center rounded-md border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg
|
||||
px-3 text-xs font-medium text-components-button-secondary-accent-text
|
||||
${!readOnly ? 'cursor-pointer' : 'cursor-default opacity-50 grayscale'}`
|
||||
}
|
||||
onClick={!readOnly ? onConfigure : undefined}
|
||||
>
|
||||
@@ -110,13 +110,13 @@ const Panel: FC<Props> = ({
|
||||
{
|
||||
isConfigured && (
|
||||
<>
|
||||
<div className='flex items-center px-3 h-[18px]'>
|
||||
<div className='flex h-[18px] items-center px-3'>
|
||||
<div className='system-xs-medium text-text-tertiary'>
|
||||
{isNotion ? t('common.dataSource.notion.connectedWorkspace') : t('common.dataSource.website.configuredCrawlers')}
|
||||
</div>
|
||||
<div className='grow ml-3 border-t border-t-divider-subtle' />
|
||||
<div className='ml-3 grow border-t border-t-divider-subtle' />
|
||||
</div>
|
||||
<div className='px-3 pt-2 pb-3'>
|
||||
<div className='px-3 pb-3 pt-2'>
|
||||
{
|
||||
configuredList.map(item => (
|
||||
<ConfigItem
|
||||
|
||||
@@ -45,8 +45,8 @@ type GroupItem = {
|
||||
key: string
|
||||
name: string
|
||||
description?: string
|
||||
icon: JSX.Element
|
||||
activeIcon: JSX.Element
|
||||
icon: React.JSX.Element
|
||||
activeIcon: React.JSX.Element
|
||||
}
|
||||
|
||||
export default function AccountSetting({
|
||||
@@ -148,15 +148,15 @@ export default function AccountSetting({
|
||||
show
|
||||
onClose={onCancel}
|
||||
>
|
||||
<div className='mx-auto max-w-[1048px] h-[100vh] flex'>
|
||||
<div className='w-[44px] sm:w-[224px] pl-4 pr-6 border-r border-divider-burn flex flex-col'>
|
||||
<div className='mt-6 mb-8 px-3 py-2 text-text-primary title-2xl-semi-bold'>{t('common.userProfile.settings')}</div>
|
||||
<div className='mx-auto flex h-[100vh] max-w-[1048px]'>
|
||||
<div className='flex w-[44px] flex-col border-r border-divider-burn pl-4 pr-6 sm:w-[224px]'>
|
||||
<div className='title-2xl-semi-bold mb-8 mt-6 px-3 py-2 text-text-primary'>{t('common.userProfile.settings')}</div>
|
||||
<div className='w-full'>
|
||||
{
|
||||
menuItems.map(menuItem => (
|
||||
<div key={menuItem.key} className='mb-2'>
|
||||
{!isCurrentWorkspaceDatasetOperator && (
|
||||
<div className='py-2 pl-3 pb-1 mb-0.5 system-xs-medium-uppercase text-text-tertiary'>{menuItem.name}</div>
|
||||
<div className='system-xs-medium-uppercase mb-0.5 py-2 pb-1 pl-3 text-text-tertiary'>{menuItem.name}</div>
|
||||
)}
|
||||
<div>
|
||||
{
|
||||
@@ -164,8 +164,8 @@ export default function AccountSetting({
|
||||
<div
|
||||
key={item.key}
|
||||
className={cn(
|
||||
'flex items-center mb-0.5 p-1 pl-3 h-[37px] text-sm cursor-pointer rounded-lg',
|
||||
activeMenu === item.key ? 'bg-state-base-active text-components-menu-item-text-active system-sm-semibold' : 'text-components-menu-item-text system-sm-medium')}
|
||||
'mb-0.5 flex h-[37px] cursor-pointer items-center rounded-lg p-1 pl-3 text-sm',
|
||||
activeMenu === item.key ? 'system-sm-semibold bg-state-base-active text-components-menu-item-text-active' : 'system-sm-medium text-components-menu-item-text')}
|
||||
title={item.name}
|
||||
onClick={() => setActiveMenu(item.key)}
|
||||
>
|
||||
@@ -181,27 +181,27 @@ export default function AccountSetting({
|
||||
</div>
|
||||
</div>
|
||||
<div className='relative flex w-[824px]'>
|
||||
<div className='absolute top-6 -right-11 flex flex-col items-center z-[9999]'>
|
||||
<div className='absolute -right-11 top-6 z-[9999] flex flex-col items-center'>
|
||||
<Button
|
||||
variant='tertiary'
|
||||
size='large'
|
||||
className='px-2'
|
||||
onClick={onCancel}
|
||||
>
|
||||
<RiCloseLine className='w-5 h-5' />
|
||||
<RiCloseLine className='h-5 w-5' />
|
||||
</Button>
|
||||
<div className='mt-1 text-text-tertiary system-2xs-medium-uppercase'>ESC</div>
|
||||
<div className='system-2xs-medium-uppercase mt-1 text-text-tertiary'>ESC</div>
|
||||
</div>
|
||||
<div ref={scrollRef} className='w-full pb-4 bg-components-panel-bg overflow-y-auto'>
|
||||
<div className={cn('sticky top-0 mx-8 pt-[27px] pb-2 mb-[18px] flex items-center bg-components-panel-bg z-20', scrolled && 'border-b border-divider-regular')}>
|
||||
<div className='shrink-0 text-text-primary title-2xl-semi-bold'>
|
||||
<div ref={scrollRef} className='w-full overflow-y-auto bg-components-panel-bg pb-4'>
|
||||
<div className={cn('sticky top-0 z-20 mx-8 mb-[18px] flex items-center bg-components-panel-bg pb-2 pt-[27px]', scrolled && 'border-b border-divider-regular')}>
|
||||
<div className='title-2xl-semi-bold shrink-0 text-text-primary'>
|
||||
{activeItem?.name}
|
||||
{activeItem?.description && (
|
||||
<div className='mt-1 system-sm-regular text-text-tertiary'>{activeItem?.description}</div>
|
||||
<div className='system-sm-regular mt-1 text-text-tertiary'>{activeItem?.description}</div>
|
||||
)}
|
||||
</div>
|
||||
{activeItem?.key === 'provider' && (
|
||||
<div className='grow flex justify-end'>
|
||||
<div className='flex grow justify-end'>
|
||||
<Input
|
||||
showLeftIcon
|
||||
wrapperClassName='!w-[200px]'
|
||||
@@ -212,7 +212,7 @@ export default function AccountSetting({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className='px-4 sm:px-8 pt-2'>
|
||||
<div className='px-4 pt-2 sm:px-8'>
|
||||
{activeMenu === 'provider' && <ModelProviderPage searchText={searchValue} />}
|
||||
{activeMenu === 'members' && <MembersPage />}
|
||||
{activeMenu === 'billing' && <BillingPage />}
|
||||
|
||||
@@ -53,14 +53,14 @@ const KeyInput = ({
|
||||
<div className={className}>
|
||||
<div className="mb-2 text-[13px] font-medium text-gray-800">{name}</div>
|
||||
<div className='
|
||||
flex items-center px-3 bg-white rounded-lg
|
||||
flex items-center rounded-lg bg-white px-3
|
||||
shadow-xs
|
||||
'>
|
||||
<input
|
||||
className='
|
||||
w-full py-[9px] mr-2
|
||||
text-xs font-medium text-gray-700 leading-[18px]
|
||||
appearance-none outline-none bg-transparent
|
||||
mr-2 w-full appearance-none
|
||||
bg-transparent py-[9px] text-xs font-medium
|
||||
leading-[18px] text-gray-700 outline-none
|
||||
'
|
||||
value={value}
|
||||
placeholder={placeholder}
|
||||
|
||||
@@ -27,15 +27,15 @@ const Operate = ({
|
||||
return (
|
||||
<div className='flex items-center'>
|
||||
<div className='
|
||||
flex items-center
|
||||
mr-[5px] px-3 h-7 rounded-md cursor-pointer
|
||||
mr-[5px] flex
|
||||
h-7 cursor-pointer items-center rounded-md px-3
|
||||
text-xs font-medium text-gray-700
|
||||
' onClick={onCancel} >
|
||||
{t('common.operation.cancel')}
|
||||
</div>
|
||||
<div className='
|
||||
flex items-center
|
||||
px-3 h-7 rounded-md cursor-pointer bg-primary-700
|
||||
flex h-7
|
||||
cursor-pointer items-center rounded-md bg-primary-700 px-3
|
||||
text-xs font-medium text-white
|
||||
' onClick={onSave}>
|
||||
{t('common.operation.save')}
|
||||
@@ -47,8 +47,8 @@ const Operate = ({
|
||||
if (status === 'add') {
|
||||
return (
|
||||
<div className={
|
||||
`px-3 h-[28px] bg-white border border-gray-200 rounded-md cursor-pointer
|
||||
text-xs font-medium text-gray-700 flex items-center ${disabled && 'opacity-50 cursor-default'}}`
|
||||
`flex h-[28px] cursor-pointer items-center rounded-md border border-gray-200
|
||||
bg-white px-3 text-xs font-medium text-gray-700 ${disabled && 'cursor-default opacity-50'}}`
|
||||
} onClick={() => !disabled && onAdd()}>
|
||||
{t('common.provider.addKey')}
|
||||
</div>
|
||||
@@ -60,7 +60,7 @@ const Operate = ({
|
||||
<div className='flex items-center'>
|
||||
{
|
||||
status === 'fail' && (
|
||||
<div className='flex items-center mr-4'>
|
||||
<div className='mr-4 flex items-center'>
|
||||
<div className='text-xs text-[#D92D20]'>{t('common.provider.invalidApiKey')}</div>
|
||||
<Indicator color='red' className='ml-2' />
|
||||
</div>
|
||||
@@ -72,8 +72,8 @@ const Operate = ({
|
||||
)
|
||||
}
|
||||
<div className={
|
||||
`px-3 h-[28px] bg-white border border-gray-200 rounded-md cursor-pointer
|
||||
text-xs font-medium text-gray-700 flex items-center ${disabled && 'opacity-50 cursor-default'}}`
|
||||
`flex h-[28px] cursor-pointer items-center rounded-md border border-gray-200
|
||||
bg-white px-3 text-xs font-medium text-gray-700 ${disabled && 'cursor-default opacity-50'}}`
|
||||
} onClick={() => !disabled && onEdit()}>
|
||||
{t('common.provider.editKey')}
|
||||
</div>
|
||||
|
||||
@@ -5,17 +5,17 @@ import {
|
||||
import { CheckCircle } from '@/app/components/base/icons/src/vender/solid/general'
|
||||
|
||||
export const ValidatedErrorIcon = () => {
|
||||
return <RiErrorWarningFill className='w-4 h-4 text-[#D92D20]' />
|
||||
return <RiErrorWarningFill className='h-4 w-4 text-[#D92D20]' />
|
||||
}
|
||||
|
||||
export const ValidatedSuccessIcon = () => {
|
||||
return <CheckCircle className='w-4 h-4 text-[#039855]' />
|
||||
return <CheckCircle className='h-4 w-4 text-[#039855]' />
|
||||
}
|
||||
|
||||
export const ValidatingTip = () => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<div className={'mt-2 text-primary-600 text-xs font-normal'}>
|
||||
<div className={'mt-2 text-xs font-normal text-primary-600'}>
|
||||
{t('common.provider.validating')}
|
||||
</div>
|
||||
)
|
||||
@@ -25,7 +25,7 @@ export const ValidatedErrorMessage = ({ errorMessage }: { errorMessage: string }
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div className={'mt-2 text-[#D92D20] text-xs font-normal'}>
|
||||
<div className={'mt-2 text-xs font-normal text-[#D92D20]'}>
|
||||
{t('common.provider.validatedError')}{errorMessage}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -75,9 +75,9 @@ const KeyValidator = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='mb-2 border-[0.5px] border-gray-200 bg-gray-50 rounded-md'>
|
||||
<div className='mb-2 rounded-md border-[0.5px] border-gray-200 bg-gray-50'>
|
||||
<div className={
|
||||
`flex items-center justify-between px-4 h-[52px] cursor-pointer ${isOpen && 'border-b-[0.5px] border-b-gray-200'}`
|
||||
`flex h-[52px] cursor-pointer items-center justify-between px-4 ${isOpen && 'border-b-[0.5px] border-b-gray-200'}`
|
||||
}>
|
||||
{title}
|
||||
<Operate
|
||||
@@ -108,9 +108,9 @@ const KeyValidator = ({
|
||||
/>
|
||||
))
|
||||
}
|
||||
<a className="flex items-center text-xs cursor-pointer text-primary-600" href={keyFrom.link} target='_blank' rel='noopener noreferrer'>
|
||||
<a className="flex cursor-pointer items-center text-xs text-primary-600" href={keyFrom.link} target='_blank' rel='noopener noreferrer'>
|
||||
{keyFrom.text}
|
||||
<LinkExternal02 className='w-3 h-3 ml-1 text-primary-600' />
|
||||
<LinkExternal02 className='ml-1 h-3 w-3 text-primary-600' />
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -55,12 +55,12 @@ const MembersPage = () => {
|
||||
return (
|
||||
<>
|
||||
<div className='flex flex-col'>
|
||||
<div className='flex items-center mb-4 p-3 pr-5 gap-3 bg-gradient-to-r from-background-gradient-bg-fill-chat-bg-2 to-background-gradient-bg-fill-chat-bg-1 rounded-xl border-t-[0.5px] border-l-[0.5px] border-divider-subtle'>
|
||||
<LogoEmbeddedChatHeader className='!w-12 !h-12' />
|
||||
<div className='mb-4 flex items-center gap-3 rounded-xl border-l-[0.5px] border-t-[0.5px] border-divider-subtle bg-gradient-to-r from-background-gradient-bg-fill-chat-bg-2 to-background-gradient-bg-fill-chat-bg-1 p-3 pr-5'>
|
||||
<LogoEmbeddedChatHeader className='!h-12 !w-12' />
|
||||
<div className='grow'>
|
||||
<div className='system-md-semibold text-text-secondary'>{currentWorkspace?.name}</div>
|
||||
{enableBilling && (
|
||||
<div className='mt-1 system-xs-medium text-text-tertiary'>
|
||||
<div className='system-xs-medium mt-1 text-text-tertiary'>
|
||||
{isNotUnlimitedMemberPlan
|
||||
? (
|
||||
<div className='flex space-x-1'>
|
||||
@@ -84,37 +84,37 @@ const MembersPage = () => {
|
||||
<UpgradeBtn className='mr-2' loc='member-invite' />
|
||||
)}
|
||||
<Button variant='primary' className={cn('shrink-0')} disabled={!isCurrentWorkspaceManager || isMemberFull} onClick={() => setInviteModalVisible(true)}>
|
||||
<RiUserAddLine className='w-4 h-4 mr-1' />
|
||||
<RiUserAddLine className='mr-1 h-4 w-4' />
|
||||
{t('common.members.invite')}
|
||||
</Button>
|
||||
</div>
|
||||
<div className='overflow-visible lg:overflow-visible'>
|
||||
<div className='flex items-center py-[7px] border-b border-divider-regular min-w-[480px]'>
|
||||
<div className='grow px-3 system-xs-medium-uppercase text-text-tertiary'>{t('common.members.name')}</div>
|
||||
<div className='shrink-0 w-[104px] system-xs-medium-uppercase text-text-tertiary'>{t('common.members.lastActive')}</div>
|
||||
<div className='shrink-0 w-[96px] px-3 system-xs-medium-uppercase text-text-tertiary'>{t('common.members.role')}</div>
|
||||
<div className='flex min-w-[480px] items-center border-b border-divider-regular py-[7px]'>
|
||||
<div className='system-xs-medium-uppercase grow px-3 text-text-tertiary'>{t('common.members.name')}</div>
|
||||
<div className='system-xs-medium-uppercase w-[104px] shrink-0 text-text-tertiary'>{t('common.members.lastActive')}</div>
|
||||
<div className='system-xs-medium-uppercase w-[96px] shrink-0 px-3 text-text-tertiary'>{t('common.members.role')}</div>
|
||||
</div>
|
||||
<div className='min-w-[480px] relative'>
|
||||
<div className='relative min-w-[480px]'>
|
||||
{
|
||||
accounts.map(account => (
|
||||
<div key={account.id} className='flex border-b border-divider-subtle'>
|
||||
<div className='grow flex items-center py-2 px-3'>
|
||||
<div className='flex grow items-center px-3 py-2'>
|
||||
<Avatar avatar={account.avatar_url} size={24} className='mr-2' name={account.name} />
|
||||
<div className=''>
|
||||
<div className='text-text-secondary system-sm-medium'>
|
||||
<div className='system-sm-medium text-text-secondary'>
|
||||
{account.name}
|
||||
{account.status === 'pending' && <span className='ml-1 system-xs-medium text-text-warning'>{t('common.members.pending')}</span>}
|
||||
{account.status === 'pending' && <span className='system-xs-medium ml-1 text-text-warning'>{t('common.members.pending')}</span>}
|
||||
{userProfile.email === account.email && <span className='system-xs-regular text-text-tertiary'>{t('common.members.you')}</span>}
|
||||
</div>
|
||||
<div className='text-text-tertiary system-xs-regular'>{account.email}</div>
|
||||
<div className='system-xs-regular text-text-tertiary'>{account.email}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='shrink-0 flex items-center w-[104px] py-2 system-sm-regular text-text-secondary'>{dayjs(Number((account.last_active_at || account.created_at)) * 1000).locale(locale === 'zh-Hans' ? 'zh-cn' : 'en').fromNow()}</div>
|
||||
<div className='shrink-0 w-[96px] flex items-center'>
|
||||
<div className='system-sm-regular flex w-[104px] shrink-0 items-center py-2 text-text-secondary'>{dayjs(Number((account.last_active_at || account.created_at)) * 1000).locale(locale === 'zh-Hans' ? 'zh-cn' : 'en').fromNow()}</div>
|
||||
<div className='flex w-[96px] shrink-0 items-center'>
|
||||
{
|
||||
((isCurrentWorkspaceOwner && account.role !== 'owner') || (isCurrentWorkspaceManager && !['owner', 'admin'].includes(account.role)))
|
||||
? <Operation member={account} operatorRole={currentWorkspace.role} onOperate={mutate} />
|
||||
: <div className='px-3 system-sm-regular text-text-secondary'>{RoleMap[account.role] || RoleMap.normal}</div>
|
||||
: <div className='system-sm-regular px-3 text-text-secondary'>{RoleMap[account.role] || RoleMap.normal}</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -58,20 +58,20 @@ const InviteModal = ({
|
||||
return (
|
||||
<div className={cn(s.wrap)}>
|
||||
<Modal overflowVisible isShow onClose={() => { }} className={cn(s.modal)}>
|
||||
<div className='flex justify-between mb-2'>
|
||||
<div className='mb-2 flex justify-between'>
|
||||
<div className='text-xl font-semibold text-text-primary'>{t('common.members.inviteTeamMember')}</div>
|
||||
<RiCloseLine className='w-4 h-4 cursor-pointer text-text-tertiary' onClick={onCancel} />
|
||||
<RiCloseLine className='h-4 w-4 cursor-pointer text-text-tertiary' onClick={onCancel} />
|
||||
</div>
|
||||
<div className='mb-3 text-[13px] text-text-tertiary'>{t('common.members.inviteTeamMemberTip')}</div>
|
||||
{!isEmailSetup && (
|
||||
<div className='grow basis-0 overflow-y-auto pb-4'>
|
||||
<div className='relative mb-1 p-2 rounded-xl border border-components-panel-border shadow-xs'>
|
||||
<div className='absolute top-0 left-0 w-full h-full rounded-xl opacity-40' style={{ background: 'linear-gradient(92deg, rgba(255, 171, 0, 0.25) 18.12%, rgba(255, 255, 255, 0.00) 167.31%)' }}></div>
|
||||
<div className='relative flex items-start w-full h-full'>
|
||||
<div className='shrink-0 mr-0.5 p-0.5'>
|
||||
<RiErrorWarningFill className='w-5 h-5 text-text-warning' />
|
||||
<div className='relative mb-1 rounded-xl border border-components-panel-border p-2 shadow-xs'>
|
||||
<div className='absolute left-0 top-0 h-full w-full rounded-xl opacity-40' style={{ background: 'linear-gradient(92deg, rgba(255, 171, 0, 0.25) 18.12%, rgba(255, 255, 255, 0.00) 167.31%)' }}></div>
|
||||
<div className='relative flex h-full w-full items-start'>
|
||||
<div className='mr-0.5 shrink-0 p-0.5'>
|
||||
<RiErrorWarningFill className='h-5 w-5 text-text-warning' />
|
||||
</div>
|
||||
<div className='text-text-primary system-xs-medium'>
|
||||
<div className='system-xs-medium text-text-primary'>
|
||||
<span>{t('common.members.emailNotSetup')}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -81,10 +81,10 @@ const InviteModal = ({
|
||||
|
||||
<div>
|
||||
<div className='mb-2 text-sm font-medium text-text-primary'>{t('common.members.email')}</div>
|
||||
<div className='mb-8 h-36 flex items-stretch'>
|
||||
<div className='mb-8 flex h-36 items-stretch'>
|
||||
<ReactMultiEmail
|
||||
className={cn('w-full pt-2 px-3 outline-none !bg-components-input-bg-normal border-components-input-border-active',
|
||||
'appearance-none text-sm !text-text-primary rounded-lg overflow-y-auto',
|
||||
className={cn('w-full border-components-input-border-active !bg-components-input-bg-normal px-3 pt-2 outline-none',
|
||||
'appearance-none overflow-y-auto rounded-lg text-sm !text-text-primary',
|
||||
)}
|
||||
autoFocus
|
||||
emails={emails}
|
||||
|
||||
@@ -34,53 +34,53 @@ const RoleSelector = ({ value, onChange }: RoleSelectorProps) => {
|
||||
onClick={() => setOpen(v => !v)}
|
||||
className='block'
|
||||
>
|
||||
<div className={cn('flex items-center px-3 py-2 rounded-lg bg-components-input-bg-normal cursor-pointer hover:bg-state-base-hover', open && 'bg-state-base-hover')}>
|
||||
<div className='grow mr-2 text-text-primary text-sm leading-5'>{t('common.members.invitedAsRole', { role: t(`common.members.${toHump(value)}`) })}</div>
|
||||
<RiArrowDownSLine className='shrink-0 w-4 h-4 text-text-secondary' />
|
||||
<div className={cn('flex cursor-pointer items-center rounded-lg bg-components-input-bg-normal px-3 py-2 hover:bg-state-base-hover', open && 'bg-state-base-hover')}>
|
||||
<div className='mr-2 grow text-sm leading-5 text-text-primary'>{t('common.members.invitedAsRole', { role: t(`common.members.${toHump(value)}`) })}</div>
|
||||
<RiArrowDownSLine className='h-4 w-4 shrink-0 text-text-secondary' />
|
||||
</div>
|
||||
</PortalToFollowElemTrigger>
|
||||
<PortalToFollowElemContent className='z-[1002]'>
|
||||
<div className='relative w-[336px] rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg'>
|
||||
<div className='p-1'>
|
||||
<div className='p-2 rounded-lg hover:bg-state-base-hover cursor-pointer' onClick={() => {
|
||||
<div className='cursor-pointer rounded-lg p-2 hover:bg-state-base-hover' onClick={() => {
|
||||
onChange('normal')
|
||||
setOpen(false)
|
||||
}}>
|
||||
<div className='relative pl-5'>
|
||||
<div className='text-text-secondary text-sm leading-5'>{t('common.members.normal')}</div>
|
||||
<div className='text-text-tertiary text-xs leading-[18px]'>{t('common.members.normalTip')}</div>
|
||||
{value === 'normal' && <Check className='absolute top-0.5 left-0 w-4 h-4 text-text-accent'/>}
|
||||
<div className='text-sm leading-5 text-text-secondary'>{t('common.members.normal')}</div>
|
||||
<div className='text-xs leading-[18px] text-text-tertiary'>{t('common.members.normalTip')}</div>
|
||||
{value === 'normal' && <Check className='absolute left-0 top-0.5 h-4 w-4 text-text-accent'/>}
|
||||
</div>
|
||||
</div>
|
||||
<div className='p-2 rounded-lg hover:bg-state-base-hover cursor-pointer' onClick={() => {
|
||||
<div className='cursor-pointer rounded-lg p-2 hover:bg-state-base-hover' onClick={() => {
|
||||
onChange('editor')
|
||||
setOpen(false)
|
||||
}}>
|
||||
<div className='relative pl-5'>
|
||||
<div className='text-text-secondary text-sm leading-5'>{t('common.members.editor')}</div>
|
||||
<div className='text-text-tertiary text-xs leading-[18px]'>{t('common.members.editorTip')}</div>
|
||||
{value === 'editor' && <Check className='absolute top-0.5 left-0 w-4 h-4 text-text-accent'/>}
|
||||
<div className='text-sm leading-5 text-text-secondary'>{t('common.members.editor')}</div>
|
||||
<div className='text-xs leading-[18px] text-text-tertiary'>{t('common.members.editorTip')}</div>
|
||||
{value === 'editor' && <Check className='absolute left-0 top-0.5 h-4 w-4 text-text-accent'/>}
|
||||
</div>
|
||||
</div>
|
||||
<div className='p-2 rounded-lg hover:bg-state-base-hover cursor-pointer' onClick={() => {
|
||||
<div className='cursor-pointer rounded-lg p-2 hover:bg-state-base-hover' onClick={() => {
|
||||
onChange('admin')
|
||||
setOpen(false)
|
||||
}}>
|
||||
<div className='relative pl-5'>
|
||||
<div className='text-text-secondary text-sm leading-5'>{t('common.members.admin')}</div>
|
||||
<div className='text-text-tertiary text-xs leading-[18px]'>{t('common.members.adminTip')}</div>
|
||||
{value === 'admin' && <Check className='absolute top-0.5 left-0 w-4 h-4 text-text-accent'/>}
|
||||
<div className='text-sm leading-5 text-text-secondary'>{t('common.members.admin')}</div>
|
||||
<div className='text-xs leading-[18px] text-text-tertiary'>{t('common.members.adminTip')}</div>
|
||||
{value === 'admin' && <Check className='absolute left-0 top-0.5 h-4 w-4 text-text-accent'/>}
|
||||
</div>
|
||||
</div>
|
||||
{datasetOperatorEnabled && (
|
||||
<div className='p-2 rounded-lg hover:bg-state-base-hover cursor-pointer' onClick={() => {
|
||||
<div className='cursor-pointer rounded-lg p-2 hover:bg-state-base-hover' onClick={() => {
|
||||
onChange('dataset_operator')
|
||||
setOpen(false)
|
||||
}}>
|
||||
<div className='relative pl-5'>
|
||||
<div className='text-text-secondary text-sm leading-5'>{t('common.members.datasetOperator')}</div>
|
||||
<div className='text-text-tertiary text-xs leading-[18px]'>{t('common.members.datasetOperatorTip')}</div>
|
||||
{value === 'dataset_operator' && <Check className='absolute top-0.5 left-0 w-4 h-4 text-text-accent'/>}
|
||||
<div className='text-sm leading-5 text-text-secondary'>{t('common.members.datasetOperator')}</div>
|
||||
<div className='text-xs leading-[18px] text-text-tertiary'>{t('common.members.datasetOperatorTip')}</div>
|
||||
{value === 'dataset_operator' && <Check className='absolute left-0 top-0.5 h-4 w-4 text-text-accent'/>}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -30,15 +30,15 @@ const InvitedModal = ({
|
||||
return (
|
||||
<div className={s.wrap}>
|
||||
<Modal isShow onClose={() => {}} className={s.modal}>
|
||||
<div className='flex justify-between mb-3'>
|
||||
<div className='mb-3 flex justify-between'>
|
||||
<div className='
|
||||
w-12 h-12 flex items-center justify-center rounded-xl
|
||||
bg-background-section-burn border-[0.5px] border-components-panel-border
|
||||
flex h-12 w-12 items-center justify-center rounded-xl
|
||||
border-[0.5px] border-components-panel-border bg-background-section-burn
|
||||
shadow-xl
|
||||
'>
|
||||
<CheckCircleIcon className='w-[22px] h-[22px] text-[#039855]' />
|
||||
<CheckCircleIcon className='h-[22px] w-[22px] text-[#039855]' />
|
||||
</div>
|
||||
<XMarkIcon className='w-4 h-4 cursor-pointer' onClick={onCancel} />
|
||||
<XMarkIcon className='h-4 w-4 cursor-pointer' onClick={onCancel} />
|
||||
</div>
|
||||
<div className='mb-1 text-xl font-semibold text-text-primary'>{t('common.members.invitationSent')}</div>
|
||||
{!IS_CE_EDITION && (
|
||||
@@ -47,11 +47,11 @@ const InvitedModal = ({
|
||||
{IS_CE_EDITION && (
|
||||
<>
|
||||
<div className='mb-5 text-sm text-text-tertiary'>{t('common.members.invitationSentTip')}</div>
|
||||
<div className='flex flex-col gap-2 mb-9'>
|
||||
<div className='mb-9 flex flex-col gap-2'>
|
||||
{
|
||||
!!successInvitationResults.length
|
||||
&& <>
|
||||
<div className='py-2 text-sm font-Medium text-text-primary'>{t('common.members.invitationLink')}</div>
|
||||
<div className='font-Medium py-2 text-sm text-text-primary'>{t('common.members.invitationLink')}</div>
|
||||
{successInvitationResults.map(item =>
|
||||
<InvitationLink key={item.email} value={item} />)}
|
||||
</>
|
||||
@@ -59,17 +59,17 @@ const InvitedModal = ({
|
||||
{
|
||||
!!failedInvitationResults.length
|
||||
&& <>
|
||||
<div className='py-2 text-sm font-Medium text-text-primary'>{t('common.members.failedInvitationEmails')}</div>
|
||||
<div className='font-Medium py-2 text-sm text-text-primary'>{t('common.members.failedInvitationEmails')}</div>
|
||||
<div className='flex flex-wrap justify-between gap-y-1'>
|
||||
{
|
||||
failedInvitationResults.map(item =>
|
||||
<div key={item.email} className='flex justify-center border border-red-300 rounded-md px-1 bg-orange-50'>
|
||||
<div key={item.email} className='flex justify-center rounded-md border border-red-300 bg-orange-50 px-1'>
|
||||
<Tooltip
|
||||
popupContent={item.message}
|
||||
>
|
||||
<div className='flex justify-center items-center text-sm gap-1'>
|
||||
<div className='flex items-center justify-center gap-1 text-sm'>
|
||||
{item.email}
|
||||
<RiQuestionLine className='w-4 h-4 text-red-300' />
|
||||
<RiQuestionLine className='h-4 w-4 text-red-300' />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>,
|
||||
|
||||
@@ -35,21 +35,21 @@ const InvitationLink = ({
|
||||
}, [isCopied])
|
||||
|
||||
return (
|
||||
<div className='flex rounded-lg bg-components-input-bg-normal hover:bg-state-base-hover border border-components-input-border-active py-2 items-center'>
|
||||
<div className="flex items-center grow h-5">
|
||||
<div className='grow text-[13px] relative h-full'>
|
||||
<div className='flex items-center rounded-lg border border-components-input-border-active bg-components-input-bg-normal py-2 hover:bg-state-base-hover'>
|
||||
<div className="flex h-5 grow items-center">
|
||||
<div className='relative h-full grow text-[13px]'>
|
||||
<Tooltip
|
||||
popupContent={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`}
|
||||
>
|
||||
<div className='absolute top-0 left-0 w-full pl-2 pr-2 truncate cursor-pointer r-0' onClick={copyHandle}>{value.url}</div>
|
||||
<div className='r-0 absolute left-0 top-0 w-full cursor-pointer truncate pl-2 pr-2' onClick={copyHandle}>{value.url}</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className="shrink-0 h-4 bg-divider-regular border" />
|
||||
<div className="h-4 shrink-0 border bg-divider-regular" />
|
||||
<Tooltip
|
||||
popupContent={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`}
|
||||
>
|
||||
<div className="px-0.5 shrink-0">
|
||||
<div className={`box-border w-[30px] h-[30px] flex items-center justify-center rounded-lg hover:bg-state-base-hover cursor-pointer ${s.copyIcon} ${isCopied ? s.copied : ''}`} onClick={copyHandle}>
|
||||
<div className="shrink-0 px-0.5">
|
||||
<div className={`box-border flex h-[30px] w-[30px] cursor-pointer items-center justify-center rounded-lg hover:bg-state-base-hover ${s.copyIcon} ${isCopied ? s.copied : ''}`} onClick={copyHandle}>
|
||||
</div>
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Fragment, useMemo } from 'react'
|
||||
import { useContext } from 'use-context-selector'
|
||||
import { Menu, Transition } from '@headlessui/react'
|
||||
import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react'
|
||||
import { CheckIcon, ChevronDownIcon } from '@heroicons/react/24/outline'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import cn from '@/utils/classnames'
|
||||
@@ -72,14 +72,14 @@ const Operation = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<Menu as="div" className="relative w-full h-full">
|
||||
<Menu as="div" className="relative h-full w-full">
|
||||
{
|
||||
({ open }) => (
|
||||
<>
|
||||
<Menu.Button className={cn('group px-3 flex items-center justify-between w-full h-full system-sm-regular text-text-secondary cursor-pointer hover:bg-state-base-hover', open && 'bg-state-base-hover')}>
|
||||
<MenuButton className={cn('system-sm-regular group flex h-full w-full cursor-pointer items-center justify-between px-3 text-text-secondary hover:bg-state-base-hover', open && 'bg-state-base-hover')}>
|
||||
{RoleMap[member.role] || RoleMap.normal}
|
||||
<ChevronDownIcon className={cn('w-4 h-4 group-hover:block', open ? 'block' : 'hidden')} />
|
||||
</Menu.Button>
|
||||
<ChevronDownIcon className={cn('h-4 w-4 group-hover:block', open ? 'block' : 'hidden')} />
|
||||
</MenuButton>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
enter="transition ease-out duration-100"
|
||||
@@ -89,40 +89,40 @@ const Operation = ({
|
||||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<Menu.Items
|
||||
className={cn('absolute origin-top-right right-0 top-[52px] z-10 bg-components-panel-bg-blur backdrop-blur-sm rounded-xl border-[0.5px] border-components-panel-border shadow-lg')}
|
||||
<MenuItems
|
||||
className={cn('absolute right-0 top-[52px] z-10 origin-top-right rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg backdrop-blur-sm')}
|
||||
>
|
||||
<div className="p-1">
|
||||
{
|
||||
roleList.map(role => (
|
||||
<Menu.Item key={role}>
|
||||
<div className='flex px-3 py-2 cursor-pointer hover:bg-state-base-hover rounded-lg' onClick={() => handleUpdateMemberRole(role)}>
|
||||
<MenuItem key={role}>
|
||||
<div className='flex cursor-pointer rounded-lg px-3 py-2 hover:bg-state-base-hover' onClick={() => handleUpdateMemberRole(role)}>
|
||||
{
|
||||
role === member.role
|
||||
? <CheckIcon className='w-4 h-4 mt-[2px] mr-1 text-text-accent' />
|
||||
: <div className='w-4 h-4 mt-[2px] mr-1 text-text-accent' />
|
||||
? <CheckIcon className='mr-1 mt-[2px] h-4 w-4 text-text-accent' />
|
||||
: <div className='mr-1 mt-[2px] h-4 w-4 text-text-accent' />
|
||||
}
|
||||
<div>
|
||||
<div className='system-sm-semibold text-text-secondary whitespace-nowrap'>{t(`common.members.${toHump(role)}`)}</div>
|
||||
<div className='system-xs-regular text-text-tertiary whitespace-nowrap'>{t(`common.members.${toHump(role)}Tip`)}</div>
|
||||
<div className='system-sm-semibold whitespace-nowrap text-text-secondary'>{t(`common.members.${toHump(role)}`)}</div>
|
||||
<div className='system-xs-regular whitespace-nowrap text-text-tertiary'>{t(`common.members.${toHump(role)}Tip`)}</div>
|
||||
</div>
|
||||
</div>
|
||||
</Menu.Item>
|
||||
</MenuItem>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
<Menu.Item>
|
||||
<div className='p-1 border-t border-divider-subtle'>
|
||||
<div className='flex px-3 py-2 cursor-pointer hover:bg-state-base-hover rounded-lg' onClick={handleDeleteMemberOrCancelInvitation}>
|
||||
<div className='w-4 h-4 mt-[2px] mr-1 text-text-accent' />
|
||||
<MenuItem>
|
||||
<div className='border-t border-divider-subtle p-1'>
|
||||
<div className='flex cursor-pointer rounded-lg px-3 py-2 hover:bg-state-base-hover' onClick={handleDeleteMemberOrCancelInvitation}>
|
||||
<div className='mr-1 mt-[2px] h-4 w-4 text-text-accent' />
|
||||
<div>
|
||||
<div className='system-sm-semibold text-text-secondary whitespace-nowrap'>{t('common.members.removeFromTeam')}</div>
|
||||
<div className='system-xs-regular text-text-tertiary whitespace-nowrap'>{t('common.members.removeFromTeamTip')}</div>
|
||||
<div className='system-sm-semibold whitespace-nowrap text-text-secondary'>{t('common.members.removeFromTeam')}</div>
|
||||
<div className='system-xs-regular whitespace-nowrap text-text-tertiary'>{t('common.members.removeFromTeamTip')}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Menu.Item>
|
||||
</Menu.Items>
|
||||
</MenuItem>
|
||||
</MenuItems>
|
||||
</Transition>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Fragment, useCallback, useEffect } from 'react'
|
||||
import type { ReactNode } from 'react'
|
||||
import { Dialog, Transition } from '@headlessui/react'
|
||||
import { Dialog, DialogPanel, Transition, TransitionChild } from '@headlessui/react'
|
||||
import cn from '@/utils/classnames'
|
||||
|
||||
type DialogProps = {
|
||||
@@ -20,8 +20,10 @@ const MenuDialog = ({
|
||||
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
if (event.key === 'Escape')
|
||||
if (event.key === 'Escape') {
|
||||
event.preventDefault()
|
||||
close()
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', handleKeyDown)
|
||||
@@ -32,23 +34,21 @@ const MenuDialog = ({
|
||||
|
||||
return (
|
||||
<Transition appear show={show} as={Fragment}>
|
||||
<Dialog as="div" className="relative z-[60]" onClose={() => {}}>
|
||||
<Dialog as="div" className="relative z-[60]" onClose={() => { }}>
|
||||
<div className="fixed inset-0">
|
||||
<div className="flex flex-col items-center justify-center min-h-full">
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 scale-95"
|
||||
enterTo="opacity-100 scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 scale-100"
|
||||
leaveTo="opacity-0 scale-95"
|
||||
>
|
||||
<Dialog.Panel className={cn('grow relative w-full h-full p-0 overflow-hidden text-left align-middle transition-all transform bg-background-sidenav-bg backdrop-blur-md', className)}>
|
||||
<div className='absolute top-0 right-0 h-full w-1/2 bg-components-panel-bg' />
|
||||
<div className="flex min-h-full flex-col items-center justify-center">
|
||||
<TransitionChild>
|
||||
<DialogPanel className={cn(
|
||||
'relative h-full w-full grow overflow-hidden bg-background-sidenav-bg p-0 text-left align-middle backdrop-blur-md transition-all',
|
||||
'duration-300 ease-in data-[closed]:scale-95 data-[closed]:opacity-0',
|
||||
'data-[enter]:scale-100 data-[enter]:opacity-100',
|
||||
'data-[enter]:scale-95 data-[leave]:opacity-0',
|
||||
className,
|
||||
)}>
|
||||
<div className='absolute right-0 top-0 h-full w-1/2 bg-components-panel-bg' />
|
||||
{children}
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</DialogPanel>
|
||||
</TransitionChild>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
|
||||
@@ -109,17 +109,17 @@ const ModelProviderPage = ({ searchText }: Props) => {
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className='relative pt-1 -mt-2'>
|
||||
<div className={cn('flex items-center mb-2')}>
|
||||
<div className='grow text-text-primary system-md-semibold'>{t('common.modelProvider.models')}</div>
|
||||
<div className='relative -mt-2 pt-1'>
|
||||
<div className={cn('mb-2 flex items-center')}>
|
||||
<div className='system-md-semibold grow text-text-primary'>{t('common.modelProvider.models')}</div>
|
||||
<div className={cn(
|
||||
'shrink-0 relative flex items-center justify-end gap-2 p-px rounded-lg border border-transparent',
|
||||
defaultModelNotConfigured && 'pl-2 bg-components-panel-bg-blur border-components-panel-border shadow-xs',
|
||||
'relative flex shrink-0 items-center justify-end gap-2 rounded-lg border border-transparent p-px',
|
||||
defaultModelNotConfigured && 'border-components-panel-border bg-components-panel-bg-blur pl-2 shadow-xs',
|
||||
)}>
|
||||
{defaultModelNotConfigured && <div className='absolute top-0 bottom-0 right-0 left-0 opacity-40' style={{ background: 'linear-gradient(92deg, rgba(247, 144, 9, 0.25) 0%, rgba(255, 255, 255, 0.00) 100%)' }} />}
|
||||
{defaultModelNotConfigured && <div className='absolute bottom-0 left-0 right-0 top-0 opacity-40' style={{ background: 'linear-gradient(92deg, rgba(247, 144, 9, 0.25) 0%, rgba(255, 255, 255, 0.00) 100%)' }} />}
|
||||
{defaultModelNotConfigured && (
|
||||
<div className='flex items-center gap-1 text-text-primary system-xs-medium'>
|
||||
<RiAlertFill className='w-4 h-4 text-text-warning-secondary' />
|
||||
<div className='system-xs-medium flex items-center gap-1 text-text-primary'>
|
||||
<RiAlertFill className='h-4 w-4 text-text-warning-secondary' />
|
||||
{t('common.modelProvider.notConfigured')}
|
||||
</div>
|
||||
)}
|
||||
@@ -134,12 +134,12 @@ const ModelProviderPage = ({ searchText }: Props) => {
|
||||
</div>
|
||||
</div>
|
||||
{!filteredConfiguredProviders?.length && (
|
||||
<div className='mb-2 p-4 rounded-[10px] bg-workflow-process-bg'>
|
||||
<div className='w-10 h-10 flex items-center justify-center rounded-[10px] border-[0.5px] border-components-card-border bg-components-card-bg shadow-lg backdrop-blur'>
|
||||
<RiBrainLine className='w-5 h-5 text-text-primary' />
|
||||
<div className='mb-2 rounded-[10px] bg-workflow-process-bg p-4'>
|
||||
<div className='flex h-10 w-10 items-center justify-center rounded-[10px] border-[0.5px] border-components-card-border bg-components-card-bg shadow-lg backdrop-blur'>
|
||||
<RiBrainLine className='h-5 w-5 text-text-primary' />
|
||||
</div>
|
||||
<div className='mt-2 text-text-secondary system-sm-medium'>{t('common.modelProvider.emptyProviderTitle')}</div>
|
||||
<div className='mt-1 text-text-tertiary system-xs-regular'>{t('common.modelProvider.emptyProviderTip')}</div>
|
||||
<div className='system-sm-medium mt-2 text-text-secondary'>{t('common.modelProvider.emptyProviderTitle')}</div>
|
||||
<div className='system-xs-regular mt-1 text-text-tertiary'>{t('common.modelProvider.emptyProviderTip')}</div>
|
||||
</div>
|
||||
)}
|
||||
{!!filteredConfiguredProviders?.length && (
|
||||
@@ -155,7 +155,7 @@ const ModelProviderPage = ({ searchText }: Props) => {
|
||||
)}
|
||||
{!!filteredNotConfiguredProviders?.length && (
|
||||
<>
|
||||
<div className='flex items-center mb-2 pt-2 text-text-primary system-md-semibold'>{t('common.modelProvider.toBeConfigured')}</div>
|
||||
<div className='system-md-semibold mb-2 flex items-center pt-2 text-text-primary'>{t('common.modelProvider.toBeConfigured')}</div>
|
||||
<div className='relative'>
|
||||
{filteredNotConfiguredProviders?.map(provider => (
|
||||
<ProviderAddedCard
|
||||
@@ -171,15 +171,15 @@ const ModelProviderPage = ({ searchText }: Props) => {
|
||||
<div className='mb-2'>
|
||||
<Divider className='!mt-4 h-px' />
|
||||
<div className='flex items-center justify-between'>
|
||||
<div className='flex items-center gap-1 text-text-primary system-md-semibold cursor-pointer' onClick={() => setCollapse(!collapse)}>
|
||||
<RiArrowDownSLine className={cn('w-4 h-4', collapse && '-rotate-90')} />
|
||||
<div className='system-md-semibold flex cursor-pointer items-center gap-1 text-text-primary' onClick={() => setCollapse(!collapse)}>
|
||||
<RiArrowDownSLine className={cn('h-4 w-4', collapse && '-rotate-90')} />
|
||||
{t('common.modelProvider.installProvider')}
|
||||
</div>
|
||||
<div className='flex items-center mb-2 pt-2'>
|
||||
<span className='pr-1 text-text-tertiary system-sm-regular'>{t('common.modelProvider.discoverMore')}</span>
|
||||
<Link target="_blank" href={`${MARKETPLACE_URL_PREFIX}`} className='inline-flex items-center system-sm-medium text-text-accent'>
|
||||
<div className='mb-2 flex items-center pt-2'>
|
||||
<span className='system-sm-regular pr-1 text-text-tertiary'>{t('common.modelProvider.discoverMore')}</span>
|
||||
<Link target="_blank" href={`${MARKETPLACE_URL_PREFIX}`} className='system-sm-medium inline-flex items-center text-text-accent'>
|
||||
{t('plugin.marketplace.difyMarketplace')}
|
||||
<RiArrowRightUpLine className='w-4 h-4' />
|
||||
<RiArrowRightUpLine className='h-4 w-4' />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -23,13 +23,13 @@ const ModelIcon: FC<ModelIconProps> = ({
|
||||
}) => {
|
||||
const language = useLanguage()
|
||||
if (provider?.provider.includes('openai') && modelName?.includes('gpt-4o'))
|
||||
return <div className='flex items-center justify-center'><OpenaiBlue className={cn('w-5 h-5', className)} /></div>
|
||||
return <div className='flex items-center justify-center'><OpenaiBlue className={cn('h-5 w-5', className)} /></div>
|
||||
if (provider?.provider.includes('openai') && modelName?.startsWith('gpt-4'))
|
||||
return <div className='flex items-center justify-center'><OpenaiViolet className={cn('w-5 h-5', className)} /></div>
|
||||
return <div className='flex items-center justify-center'><OpenaiViolet className={cn('h-5 w-5', className)} /></div>
|
||||
|
||||
if (provider?.icon_small) {
|
||||
return (
|
||||
<div className={cn('flex items-center justify-center w-5 h-5', isDeprecated && 'opacity-50', className)}>
|
||||
<div className={cn('flex h-5 w-5 items-center justify-center', isDeprecated && 'opacity-50', className)}>
|
||||
<img alt='model-icon' src={renderI18nObject(provider.icon_small, language)}/>
|
||||
</div>
|
||||
)
|
||||
@@ -37,11 +37,11 @@ const ModelIcon: FC<ModelIconProps> = ({
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
'flex items-center justify-center rounded-md border-[0.5px] w-5 h-5 border-components-panel-border-subtle bg-background-default-subtle',
|
||||
'flex h-5 w-5 items-center justify-center rounded-md border-[0.5px] border-components-panel-border-subtle bg-background-default-subtle',
|
||||
className,
|
||||
)}>
|
||||
<div className='flex w-5 h-5 items-center justify-center opacity-35'>
|
||||
<Group className='text-text-tertiary w-3 h-3' />
|
||||
<div className='flex h-5 w-5 items-center justify-center opacity-35'>
|
||||
<Group className='h-3 w-3 text-text-tertiary' />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -153,7 +153,7 @@ function Form<
|
||||
const disabled = readonly || (isEditMode && (variable === '__model_type' || variable === '__model_name'))
|
||||
return (
|
||||
<div key={variable} className={cn(itemClassName, 'py-3')}>
|
||||
<div className={cn(fieldLabelClassName, 'flex items-center py-2 system-sm-semibold text-text-secondary')}>
|
||||
<div className={cn(fieldLabelClassName, 'system-sm-semibold flex items-center py-2 text-text-secondary')}>
|
||||
{label[language] || label.en_US}
|
||||
{required && (
|
||||
<span className='ml-1 text-red-500'>*</span>
|
||||
@@ -187,14 +187,14 @@ function Form<
|
||||
|
||||
return (
|
||||
<div key={variable} className={cn(itemClassName, 'py-3')}>
|
||||
<div className={cn(fieldLabelClassName, 'flex items-center py-2 system-sm-semibold text-text-secondary')}>
|
||||
<div className={cn(fieldLabelClassName, 'system-sm-semibold flex items-center py-2 text-text-secondary')}>
|
||||
{label[language] || label.en_US}
|
||||
{required && (
|
||||
<span className='ml-1 text-red-500'>*</span>
|
||||
)}
|
||||
{tooltipContent}
|
||||
</div>
|
||||
<div className={`grid grid-cols-${options?.length} gap-3`}>
|
||||
<div className={cn('grid gap-3', `grid-cols-${options?.length}`)}>
|
||||
{options.filter((option) => {
|
||||
if (option.show_on.length)
|
||||
return option.show_on.every(showOnItem => value[showOnItem.variable] === showOnItem.value)
|
||||
@@ -203,8 +203,8 @@ function Form<
|
||||
}).map(option => (
|
||||
<div
|
||||
className={`
|
||||
flex items-center gap-2 px-3 py-2 rounded-lg border border-components-option-card-option-border bg-components-option-card-option-bg cursor-pointer
|
||||
${value[variable] === option.value && 'bg-components-option-card-option-selected-bg border-[1.5px] border-components-option-card-option-selected-border shadow-sm'}
|
||||
flex cursor-pointer items-center gap-2 rounded-lg border border-components-option-card-option-border bg-components-option-card-option-bg px-3 py-2
|
||||
${value[variable] === option.value && 'border-[1.5px] border-components-option-card-option-selected-border bg-components-option-card-option-selected-bg shadow-sm'}
|
||||
${disabled && '!cursor-not-allowed opacity-60'}
|
||||
`}
|
||||
onClick={() => handleFormChange(variable, option.value)}
|
||||
@@ -232,7 +232,7 @@ function Form<
|
||||
|
||||
return (
|
||||
<div key={variable} className={cn(itemClassName, 'py-3')}>
|
||||
<div className={cn(fieldLabelClassName, 'flex items-center py-2 system-sm-semibold text-text-secondary')}>
|
||||
<div className={cn(fieldLabelClassName, 'system-sm-semibold flex items-center py-2 text-text-secondary')}>
|
||||
{label[language] || label.en_US}
|
||||
|
||||
{required && (
|
||||
@@ -269,9 +269,9 @@ function Form<
|
||||
|
||||
return (
|
||||
<div key={variable} className={cn(itemClassName, 'py-3')}>
|
||||
<div className='flex items-center justify-between py-2 system-sm-semibold text-text-secondary'>
|
||||
<div className='system-sm-semibold flex items-center justify-between py-2 text-text-secondary'>
|
||||
<div className='flex items-center space-x-2'>
|
||||
<span className={cn(fieldLabelClassName, 'flex items-center py-2 system-sm-regular text-text-secondary')}>{label[language] || label.en_US}</span>
|
||||
<span className={cn(fieldLabelClassName, 'system-sm-regular flex items-center py-2 text-text-secondary')}>{label[language] || label.en_US}</span>
|
||||
{required && (
|
||||
<span className='ml-1 text-red-500'>*</span>
|
||||
)}
|
||||
@@ -297,7 +297,7 @@ function Form<
|
||||
} = formSchema as (CredentialFormSchemaTextInput | CredentialFormSchemaSecretInput)
|
||||
return (
|
||||
<div key={variable} className={cn(itemClassName, 'py-3')}>
|
||||
<div className={cn(fieldLabelClassName, 'flex items-center py-2 system-sm-semibold text-text-secondary')}>
|
||||
<div className={cn(fieldLabelClassName, 'system-sm-semibold flex items-center py-2 text-text-secondary')}>
|
||||
{label[language] || label.en_US}
|
||||
{required && (
|
||||
<span className='ml-1 text-red-500'>*</span>
|
||||
@@ -328,7 +328,7 @@ function Form<
|
||||
} = formSchema as (CredentialFormSchemaTextInput | CredentialFormSchemaSecretInput)
|
||||
return (
|
||||
<div key={variable} className={cn(itemClassName, 'py-3')}>
|
||||
<div className={cn(fieldLabelClassName, 'flex items-center py-2 system-sm-semibold text-text-secondary')}>
|
||||
<div className={cn(fieldLabelClassName, 'system-sm-semibold flex items-center py-2 text-text-secondary')}>
|
||||
{label[language] || label.en_US}
|
||||
{required && (
|
||||
<span className='ml-1 text-red-500'>*</span>
|
||||
@@ -388,7 +388,7 @@ function Form<
|
||||
|
||||
return (
|
||||
<div key={variable} className={cn(itemClassName, 'py-3')}>
|
||||
<div className={cn(fieldLabelClassName, 'flex items-center py-2 system-sm-semibold text-text-secondary')}>
|
||||
<div className={cn(fieldLabelClassName, 'system-sm-semibold flex items-center py-2 text-text-secondary')}>
|
||||
{label[language] || label.en_US}
|
||||
{required && (
|
||||
<span className='ml-1 text-red-500'>*</span>
|
||||
|
||||
@@ -41,11 +41,11 @@ const Input: FC<InputProps> = ({
|
||||
<input
|
||||
tabIndex={0}
|
||||
className={`
|
||||
block px-3 w-full h-8 bg-components-input-bg-normal text-sm text-components-input-text-filled rounded-lg border border-transparent
|
||||
appearance-none outline-none caret-primary-600
|
||||
hover:border-components-input-border-hover hover:bg-components-input-bg-hover
|
||||
focus:bg-components-input-bg-active focus:border-components-input-border-active focus:shadow-xs
|
||||
block h-8 w-full appearance-none rounded-lg border border-transparent bg-components-input-bg-normal px-3 text-sm
|
||||
text-components-input-text-filled caret-primary-600 outline-none
|
||||
placeholder:text-sm placeholder:text-text-tertiary
|
||||
hover:border-components-input-border-hover hover:bg-components-input-bg-hover focus:border-components-input-border-active
|
||||
focus:bg-components-input-bg-active focus:shadow-xs
|
||||
${validated && 'pr-[30px]'}
|
||||
${className}
|
||||
`}
|
||||
@@ -61,8 +61,8 @@ const Input: FC<InputProps> = ({
|
||||
/>
|
||||
{
|
||||
validated && (
|
||||
<div className='absolute top-2.5 right-2.5'>
|
||||
<CheckCircle className='w-4 h-4 text-[#039855]' />
|
||||
<div className='absolute right-2.5 top-2.5'>
|
||||
<CheckCircle className='h-4 w-4 text-[#039855]' />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -277,11 +277,11 @@ const ModelModal: FC<ModelModalProps> = ({
|
||||
|
||||
return (
|
||||
<PortalToFollowElem open>
|
||||
<PortalToFollowElemContent className='w-full h-full z-[60]'>
|
||||
<PortalToFollowElemContent className='z-[60] h-full w-full'>
|
||||
<div className='fixed inset-0 flex items-center justify-center bg-black/[.25]'>
|
||||
<div className='mx-2 w-[640px] max-h-[calc(100vh-120px)] bg-components-panel-bg shadow-xl rounded-2xl overflow-y-auto'>
|
||||
<div className='mx-2 max-h-[calc(100vh-120px)] w-[640px] overflow-y-auto rounded-2xl bg-components-panel-bg shadow-xl'>
|
||||
<div className='px-8 pt-8'>
|
||||
<div className='flex items-center mb-2'>
|
||||
<div className='mb-2 flex items-center'>
|
||||
<div className='text-xl font-semibold text-text-primary'>{renderTitlePrefix()}</div>
|
||||
</div>
|
||||
|
||||
@@ -295,7 +295,7 @@ const ModelModal: FC<ModelModalProps> = ({
|
||||
isEditMode={isEditMode}
|
||||
/>
|
||||
|
||||
<div className='mt-1 mb-4 border-t-[0.5px] border-t-divider-regular' />
|
||||
<div className='mb-4 mt-1 border-t-[0.5px] border-t-divider-regular' />
|
||||
<ModelLoadBalancingConfigs withSwitch {...{
|
||||
draftConfig,
|
||||
setDraftConfig,
|
||||
@@ -304,7 +304,7 @@ const ModelModal: FC<ModelModalProps> = ({
|
||||
configurationMethod: configurateMethod,
|
||||
}} />
|
||||
|
||||
<div className='sticky bottom-0 flex justify-between items-center mt-2 -mx-2 pt-4 px-2 pb-6 flex-wrap gap-y-2 bg-components-panel-bg'>
|
||||
<div className='sticky bottom-0 -mx-2 mt-2 flex flex-wrap items-center justify-between gap-y-2 bg-components-panel-bg px-2 pb-6 pt-4'>
|
||||
{
|
||||
(provider.help && (provider.help.title || provider.help.url))
|
||||
? (
|
||||
@@ -315,7 +315,7 @@ const ModelModal: FC<ModelModalProps> = ({
|
||||
onClick={e => !provider.help.url && e.preventDefault()}
|
||||
>
|
||||
{provider.help.title?.[language] || provider.help.url[language] || provider.help.title?.en_US || provider.help.url.en_US}
|
||||
<LinkExternal02 className='ml-1 w-3 h-3' />
|
||||
<LinkExternal02 className='ml-1 h-3 w-3' />
|
||||
</a>
|
||||
)
|
||||
: <div />
|
||||
@@ -360,17 +360,17 @@ const ModelModal: FC<ModelModalProps> = ({
|
||||
{
|
||||
(validatedStatusState.status === ValidatedStatus.Error && validatedStatusState.message)
|
||||
? (
|
||||
<div className='flex px-[10px] py-3 bg-background-section-burn text-xs text-[#D92D20]'>
|
||||
<RiErrorWarningFill className='mt-[1px] mr-2 w-[14px] h-[14px]' />
|
||||
<div className='flex bg-background-section-burn px-[10px] py-3 text-xs text-[#D92D20]'>
|
||||
<RiErrorWarningFill className='mr-2 mt-[1px] h-[14px] w-[14px]' />
|
||||
{validatedStatusState.message}
|
||||
</div>
|
||||
)
|
||||
: (
|
||||
<div className='flex justify-center items-center py-3 bg-background-section-burn text-xs text-text-tertiary'>
|
||||
<Lock01 className='mr-1 w-3 h-3 text-text-tertiary' />
|
||||
<div className='flex items-center justify-center bg-background-section-burn py-3 text-xs text-text-tertiary'>
|
||||
<Lock01 className='mr-1 h-3 w-3 text-text-tertiary' />
|
||||
{t('common.modelProvider.encrypted.front')}
|
||||
<a
|
||||
className='text-text-accent mx-1'
|
||||
className='mx-1 text-text-accent'
|
||||
target='_blank' rel='noopener noreferrer'
|
||||
href='https://pycryptodome.readthedocs.io/en/latest/src/cipher/oaep.html'
|
||||
>
|
||||
|
||||
@@ -241,11 +241,11 @@ const ModelLoadBalancingEntryModal: FC<ModelModalProps> = ({
|
||||
|
||||
return (
|
||||
<PortalToFollowElem open>
|
||||
<PortalToFollowElemContent className='w-full h-full z-[60]'>
|
||||
<PortalToFollowElemContent className='z-[60] h-full w-full'>
|
||||
<div className='fixed inset-0 flex items-center justify-center bg-black/[.25]'>
|
||||
<div className='mx-2 w-[640px] max-h-[calc(100vh-120px)] bg-white shadow-xl rounded-2xl overflow-y-auto'>
|
||||
<div className='mx-2 max-h-[calc(100vh-120px)] w-[640px] overflow-y-auto rounded-2xl bg-white shadow-xl'>
|
||||
<div className='px-8 pt-8'>
|
||||
<div className='flex justify-between items-center mb-2'>
|
||||
<div className='mb-2 flex items-center justify-between'>
|
||||
<div className='text-xl font-semibold text-gray-900'>{t(isEditMode ? 'common.modelProvider.editConfig' : 'common.modelProvider.addConfig')}</div>
|
||||
</div>
|
||||
<Form
|
||||
@@ -257,7 +257,7 @@ const ModelLoadBalancingEntryModal: FC<ModelModalProps> = ({
|
||||
showOnVariableMap={showOnVariableMap}
|
||||
isEditMode={isEditMode}
|
||||
/>
|
||||
<div className='sticky bottom-0 flex justify-between items-center py-6 flex-wrap gap-y-2 bg-white'>
|
||||
<div className='sticky bottom-0 flex flex-wrap items-center justify-between gap-y-2 bg-white py-6'>
|
||||
{
|
||||
(provider.help && (provider.help.title || provider.help.url))
|
||||
? (
|
||||
@@ -268,7 +268,7 @@ const ModelLoadBalancingEntryModal: FC<ModelModalProps> = ({
|
||||
onClick={e => !provider.help.url && e.preventDefault()}
|
||||
>
|
||||
{provider.help.title?.[language] || provider.help.url[language] || provider.help.title?.en_US || provider.help.url.en_US}
|
||||
<LinkExternal02 className='ml-1 w-3 h-3' />
|
||||
<LinkExternal02 className='ml-1 h-3 w-3' />
|
||||
</a>
|
||||
)
|
||||
: <div />
|
||||
@@ -307,17 +307,17 @@ const ModelLoadBalancingEntryModal: FC<ModelModalProps> = ({
|
||||
{
|
||||
(validatedStatusState.status === ValidatedStatus.Error && validatedStatusState.message)
|
||||
? (
|
||||
<div className='flex px-[10px] py-3 bg-[#FEF3F2] text-xs text-[#D92D20]'>
|
||||
<RiErrorWarningFill className='mt-[1px] mr-2 w-[14px] h-[14px]' />
|
||||
<div className='flex bg-[#FEF3F2] px-[10px] py-3 text-xs text-[#D92D20]'>
|
||||
<RiErrorWarningFill className='mr-2 mt-[1px] h-[14px] w-[14px]' />
|
||||
{validatedStatusState.message}
|
||||
</div>
|
||||
)
|
||||
: (
|
||||
<div className='flex justify-center items-center py-3 bg-gray-50 text-xs text-gray-500'>
|
||||
<Lock01 className='mr-1 w-3 h-3 text-gray-500' />
|
||||
<div className='flex items-center justify-center bg-gray-50 py-3 text-xs text-gray-500'>
|
||||
<Lock01 className='mr-1 h-3 w-3 text-gray-500' />
|
||||
{t('common.modelProvider.encrypted.front')}
|
||||
<a
|
||||
className='text-primary-600 mx-1'
|
||||
className='mx-1 text-primary-600'
|
||||
target='_blank' rel='noopener noreferrer'
|
||||
href='https://pycryptodome.readthedocs.io/en/latest/src/cipher/oaep.html'
|
||||
>
|
||||
|
||||
@@ -37,7 +37,7 @@ const ModelName: FC<ModelNameProps> = ({
|
||||
if (!modelItem)
|
||||
return null
|
||||
return (
|
||||
<div className={cn('flex gap-0.5 items-center overflow-hidden text-ellipsis truncate text-components-input-text-filled system-sm-regular', className)}>
|
||||
<div className={cn('system-sm-regular flex items-center gap-0.5 overflow-hidden truncate text-ellipsis text-components-input-text-filled', className)}>
|
||||
<div
|
||||
className='truncate'
|
||||
title={modelItem.label[language] || modelItem.label.en_US}
|
||||
|
||||
@@ -76,7 +76,7 @@ const AgentModelTrigger: FC<AgentModelTriggerProps> = ({
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'relative group flex items-center p-1 gap-[2px] flex-grow rounded-lg bg-components-input-bg-normal cursor-pointer hover:bg-state-base-hover-alt',
|
||||
'group relative flex grow cursor-pointer items-center gap-[2px] rounded-lg bg-components-input-bg-normal p-1 hover:bg-state-base-hover-alt',
|
||||
)}
|
||||
>
|
||||
{modelId ? (
|
||||
@@ -130,20 +130,20 @@ const AgentModelTrigger: FC<AgentModelTriggerProps> = ({
|
||||
/>
|
||||
)}
|
||||
{modelProvider && !disabled && !needsConfiguration && (
|
||||
<div className="flex pr-1 items-center">
|
||||
<RiEqualizer2Line className="w-4 h-4 text-text-tertiary group-hover:text-text-secondary" />
|
||||
<div className="flex items-center pr-1">
|
||||
<RiEqualizer2Line className="h-4 w-4 text-text-tertiary group-hover:text-text-secondary" />
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div className="flex p-1 pl-2 items-center gap-1 grow">
|
||||
<span className="overflow-hidden text-ellipsis whitespace-nowrap system-sm-regular text-components-input-text-placeholder">
|
||||
<div className="flex grow items-center gap-1 p-1 pl-2">
|
||||
<span className="system-sm-regular overflow-hidden text-ellipsis whitespace-nowrap text-components-input-text-placeholder">
|
||||
{t('workflow.nodes.agent.configureModel')}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex pr-1 items-center">
|
||||
<RiEqualizer2Line className="w-4 h-4 text-text-tertiary group-hover:text-text-secondary" />
|
||||
<div className="flex items-center pr-1">
|
||||
<RiEqualizer2Line className="h-4 w-4 text-text-tertiary group-hover:text-text-secondary" />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -18,11 +18,11 @@ const ConfigurationButton = ({ modelProvider, handleOpenModal }: ConfigurationBu
|
||||
handleOpenModal(modelProvider, ConfigurationMethodEnum.predefinedModel, undefined)
|
||||
}}
|
||||
>
|
||||
<div className="flex px-[3px] justify-center items-center gap-1">
|
||||
<div className="flex items-center justify-center gap-1 px-[3px]">
|
||||
{t('workflow.nodes.agent.notAuthorized')}
|
||||
</div>
|
||||
<div className="flex w-[14px] h-[14px] justify-center items-center">
|
||||
<div className="w-2 h-2 shrink-0 rounded-[3px] border border-components-badge-status-light-warning-border-inner
|
||||
<div className="flex h-[14px] w-[14px] items-center justify-center">
|
||||
<div className="h-2 w-2 shrink-0 rounded-[3px] border border-components-badge-status-light-warning-border-inner
|
||||
bg-components-badge-status-light-warning-bg shadow-components-badge-status-light-warning-halo" />
|
||||
</div>
|
||||
</Button>
|
||||
|
||||
@@ -194,9 +194,9 @@ const ModelParameterModal: FC<ModelParameterModalProps> = ({
|
||||
</PortalToFollowElemTrigger>
|
||||
<PortalToFollowElemContent className={cn('z-[60]', portalToFollowElemContentClassName)}>
|
||||
<div className={cn(popupClassName, 'w-[389px] rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg')}>
|
||||
<div className={cn('max-h-[420px] p-4 pt-3 overflow-y-auto')}>
|
||||
<div className={cn('max-h-[420px] overflow-y-auto p-4 pt-3')}>
|
||||
<div className='relative'>
|
||||
<div className={cn('mb-1 h-6 flex items-center text-text-secondary system-sm-semibold')}>
|
||||
<div className={cn('system-sm-semibold mb-1 flex h-6 items-center text-text-secondary')}>
|
||||
{t('common.modelProvider.model').toLocaleUpperCase()}
|
||||
</div>
|
||||
<ModelSelector
|
||||
@@ -217,8 +217,8 @@ const ModelParameterModal: FC<ModelParameterModalProps> = ({
|
||||
}
|
||||
{
|
||||
!isLoading && !!parameterRules.length && (
|
||||
<div className='flex items-center justify-between mb-2'>
|
||||
<div className={cn('h-6 flex items-center text-text-secondary system-sm-semibold')}>{t('common.modelProvider.parameters')}</div>
|
||||
<div className='mb-2 flex items-center justify-between'>
|
||||
<div className={cn('system-sm-semibold flex h-6 items-center text-text-secondary')}>{t('common.modelProvider.parameters')}</div>
|
||||
{
|
||||
PROVIDER_WITH_PRESET_TONE.includes(provider) && (
|
||||
<PresetsParameter onSelect={handleSelectPresetParameter} />
|
||||
@@ -247,7 +247,7 @@ const ModelParameterModal: FC<ModelParameterModalProps> = ({
|
||||
</div>
|
||||
{!hideDebugWithMultipleModel && (
|
||||
<div
|
||||
className='flex items-center justify-between px-4 h-[50px] bg-components-section-burn border-t border-t-divider-subtle system-sm-regular text-text-accent cursor-pointer rounded-b-xl'
|
||||
className='bg-components-section-burn system-sm-regular flex h-[50px] cursor-pointer items-center justify-between rounded-b-xl border-t border-t-divider-subtle px-4 text-text-accent'
|
||||
onClick={() => onDebugWithMultipleModelChange?.()}
|
||||
>
|
||||
{
|
||||
@@ -255,7 +255,7 @@ const ModelParameterModal: FC<ModelParameterModalProps> = ({
|
||||
? t('appDebug.debugAsSingleModel')
|
||||
: t('appDebug.debugAsMultipleModel')
|
||||
}
|
||||
<ArrowNarrowLeft className='w-3 h-3 rotate-180' />
|
||||
<ArrowNarrowLeft className='h-3 w-3 rotate-180' />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -8,14 +8,14 @@ type ModelDisplayProps = {
|
||||
const ModelDisplay = ({ currentModel, modelId }: ModelDisplayProps) => {
|
||||
return currentModel ? (
|
||||
<ModelName
|
||||
className="flex px-1 py-[3px] items-center gap-1 grow"
|
||||
className="flex grow items-center gap-1 px-1 py-[3px]"
|
||||
modelItem={currentModel}
|
||||
showMode
|
||||
showFeatures
|
||||
/>
|
||||
) : (
|
||||
<div className="flex py-[3px] px-1 items-center gap-1 grow opacity-50 truncate">
|
||||
<div className="text-components-input-text-filled text-ellipsis overflow-hidden system-sm-regular">
|
||||
<div className="flex grow items-center gap-1 truncate px-1 py-[3px] opacity-50">
|
||||
<div className="system-sm-regular overflow-hidden text-ellipsis text-components-input-text-filled">
|
||||
{modelId}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -148,7 +148,7 @@ const ParameterItem: FC<ParameterItemProps> = ({
|
||||
/>}
|
||||
<input
|
||||
ref={numberInputRef}
|
||||
className='shrink-0 block ml-4 pl-3 w-16 h-8 appearance-none outline-none rounded-lg bg-components-input-bg-normal text-components-input-text-filled system-sm-regular'
|
||||
className='system-sm-regular ml-4 block h-8 w-16 shrink-0 appearance-none rounded-lg bg-components-input-bg-normal pl-3 text-components-input-text-filled outline-none'
|
||||
type='number'
|
||||
max={parameterRule.max}
|
||||
min={parameterRule.min}
|
||||
@@ -173,7 +173,7 @@ const ParameterItem: FC<ParameterItemProps> = ({
|
||||
/>}
|
||||
<input
|
||||
ref={numberInputRef}
|
||||
className='shrink-0 block ml-4 pl-3 w-16 h-8 appearance-none outline-none rounded-lg bg-components-input-bg-normal text-components-input-text-filled system-sm-regular'
|
||||
className='system-sm-regular ml-4 block h-8 w-16 shrink-0 appearance-none rounded-lg bg-components-input-bg-normal pl-3 text-components-input-text-filled outline-none'
|
||||
type='number'
|
||||
max={parameterRule.max}
|
||||
min={parameterRule.min}
|
||||
@@ -188,7 +188,7 @@ const ParameterItem: FC<ParameterItemProps> = ({
|
||||
if (parameterRule.type === 'boolean') {
|
||||
return (
|
||||
<Radio.Group
|
||||
className='w-[178px] flex items-center'
|
||||
className='flex w-[178px] items-center'
|
||||
value={renderValue ? 1 : 0}
|
||||
onChange={handleRadioChange}
|
||||
>
|
||||
@@ -201,7 +201,7 @@ const ParameterItem: FC<ParameterItemProps> = ({
|
||||
if (parameterRule.type === 'string' && !parameterRule.options?.length) {
|
||||
return (
|
||||
<input
|
||||
className={cn(isInWorkflow ? 'w-[178px]' : 'w-full', 'ml-4 flex items-center px-3 h-8 appearance-none outline-none rounded-lg bg-components-input-bg-normal text-components-input-text-filled system-sm-regular')}
|
||||
className={cn(isInWorkflow ? 'w-[178px]' : 'w-full', 'system-sm-regular ml-4 flex h-8 appearance-none items-center rounded-lg bg-components-input-bg-normal px-3 text-components-input-text-filled outline-none')}
|
||||
value={renderValue as string}
|
||||
onChange={handleStringInputChange}
|
||||
/>
|
||||
@@ -211,7 +211,7 @@ const ParameterItem: FC<ParameterItemProps> = ({
|
||||
if (parameterRule.type === 'text') {
|
||||
return (
|
||||
<textarea
|
||||
className='w-full h-20 ml-4 px-1 rounded-lg bg-components-input-bg-normal text-components-input-text-filled system-sm-regular'
|
||||
className='system-sm-regular ml-4 h-20 w-full rounded-lg bg-components-input-bg-normal px-1 text-components-input-text-filled'
|
||||
value={renderValue as string}
|
||||
onChange={handleStringInputChange}
|
||||
/>
|
||||
@@ -222,7 +222,7 @@ const ParameterItem: FC<ParameterItemProps> = ({
|
||||
return (
|
||||
<SimpleSelect
|
||||
className='!py-0'
|
||||
wrapperClassName={cn('w-full !h-8')}
|
||||
wrapperClassName={cn('!h-8 w-full')}
|
||||
defaultValue={renderValue as string}
|
||||
onSelect={handleSelect}
|
||||
items={parameterRule.options.map(option => ({ value: option, name: option }))}
|
||||
@@ -232,7 +232,7 @@ const ParameterItem: FC<ParameterItemProps> = ({
|
||||
|
||||
if (parameterRule.type === 'tag') {
|
||||
return (
|
||||
<div className={cn('w-full !h-8')}>
|
||||
<div className={cn('!h-8 w-full')}>
|
||||
<TagInput
|
||||
items={renderValue as string[]}
|
||||
onChange={handleTagChange}
|
||||
@@ -247,9 +247,9 @@ const ParameterItem: FC<ParameterItemProps> = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='flex items-center justify-between mb-2'>
|
||||
<div className='mb-2 flex items-center justify-between'>
|
||||
<div className='shrink-0 basis-1/2'>
|
||||
<div className={cn('shrink-0 w-full flex items-center')}>
|
||||
<div className={cn('flex w-full shrink-0 items-center')}>
|
||||
{
|
||||
!parameterRule.required && parameterRule.name !== 'stop' && (
|
||||
<div className='mr-2 w-7'>
|
||||
@@ -262,7 +262,7 @@ const ParameterItem: FC<ParameterItemProps> = ({
|
||||
)
|
||||
}
|
||||
<div
|
||||
className='mr-0.5 system-xs-regular text-text-secondary truncate'
|
||||
className='system-xs-regular mr-0.5 truncate text-text-secondary'
|
||||
title={parameterRule.label[language] || parameterRule.label.en_US}
|
||||
>
|
||||
{parameterRule.label[language] || parameterRule.label.en_US}
|
||||
@@ -281,7 +281,7 @@ const ParameterItem: FC<ParameterItemProps> = ({
|
||||
</div>
|
||||
{
|
||||
parameterRule.type === 'tag' && (
|
||||
<div className={cn(!isInWorkflow && 'w-[178px]', 'text-text-tertiary system-xs-regular')}>
|
||||
<div className={cn(!isInWorkflow && 'w-[178px]', 'system-xs-regular text-text-tertiary')}>
|
||||
{parameterRule?.tagPlaceholder?.[language]}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -25,7 +25,7 @@ const PresetsParameter: FC<PresetsParameterProps> = ({
|
||||
className={cn(open && 'bg-state-base-hover')}
|
||||
>
|
||||
{t('common.modelProvider.loadPresets')}
|
||||
<RiArrowDownSLine className='ml-0.5 w-3.5 h-3.5' />
|
||||
<RiArrowDownSLine className='ml-0.5 h-3.5 w-3.5' />
|
||||
</Button>
|
||||
)
|
||||
}, [t])
|
||||
@@ -42,7 +42,7 @@ const PresetsParameter: FC<PresetsParameterProps> = ({
|
||||
return {
|
||||
value: tone.id,
|
||||
text: (
|
||||
<div className='flex items-center h-full'>
|
||||
<div className='flex h-full items-center'>
|
||||
{getToneIcon(tone.id)}
|
||||
{t(`common.model.tone.${tone.name}`) as string}
|
||||
</div>
|
||||
|
||||
@@ -17,15 +17,15 @@ const StatusIndicators = ({ needsConfiguration, modelProvider, inModelList, disa
|
||||
const { data: pluginList } = useInstalledPluginList()
|
||||
const renderTooltipContent = (title: string, description?: string, linkText?: string, linkHref?: string) => {
|
||||
return (
|
||||
<div className='flex w-[240px] max-w-[240px] gap-1 flex-col px-1 py-1.5' onClick={e => e.stopPropagation()}>
|
||||
<div className='text-text-primary title-xs-semi-bold'>{title}</div>
|
||||
<div className='flex w-[240px] max-w-[240px] flex-col gap-1 px-1 py-1.5' onClick={e => e.stopPropagation()}>
|
||||
<div className='title-xs-semi-bold text-text-primary'>{title}</div>
|
||||
{description && (
|
||||
<div className='min-w-[200px] text-text-secondary body-xs-regular'>
|
||||
<div className='body-xs-regular min-w-[200px] text-text-secondary'>
|
||||
{description}
|
||||
</div>
|
||||
)}
|
||||
{linkText && linkHref && (
|
||||
<div className='text-text-accent body-xs-regular cursor-pointer z-[100]'>
|
||||
<div className='body-xs-regular z-[100] cursor-pointer text-text-accent'>
|
||||
<Link
|
||||
href={linkHref}
|
||||
onClick={(e) => {
|
||||
@@ -52,7 +52,7 @@ const StatusIndicators = ({ needsConfiguration, modelProvider, inModelList, disa
|
||||
asChild={false}
|
||||
needsDelay={false}
|
||||
>
|
||||
<RiErrorWarningFill className='w-4 h-4 text-text-destructive' />
|
||||
<RiErrorWarningFill className='h-4 w-4 text-text-destructive' />
|
||||
</Tooltip>
|
||||
) : !pluginInfo ? (
|
||||
<Tooltip
|
||||
@@ -65,7 +65,7 @@ const StatusIndicators = ({ needsConfiguration, modelProvider, inModelList, disa
|
||||
asChild={false}
|
||||
needsDelay={true}
|
||||
>
|
||||
<RiErrorWarningFill className='w-4 h-4 text-text-destructive' />
|
||||
<RiErrorWarningFill className='h-4 w-4 text-text-destructive' />
|
||||
</Tooltip>
|
||||
) : (
|
||||
<SwitchPluginVersion
|
||||
@@ -89,7 +89,7 @@ const StatusIndicators = ({ needsConfiguration, modelProvider, inModelList, disa
|
||||
asChild={false}
|
||||
needsDelay
|
||||
>
|
||||
<RiErrorWarningFill className='w-4 h-4 text-text-destructive' />
|
||||
<RiErrorWarningFill className='h-4 w-4 text-text-destructive' />
|
||||
</Tooltip>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -44,16 +44,16 @@ const Trigger: FC<TriggerProps> = ({
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'relative flex items-center px-2 h-8 rounded-lg cursor-pointer',
|
||||
'relative flex h-8 cursor-pointer items-center rounded-lg px-2',
|
||||
!isInWorkflow && 'border ring-inset hover:ring-[0.5px]',
|
||||
!isInWorkflow && (disabled ? 'border-text-warning ring-text-warning bg-state-warning-hover' : 'border-util-colors-indigo-indigo-600 ring-util-colors-indigo-indigo-600 bg-state-accent-hover'),
|
||||
isInWorkflow && 'pr-[30px] bg-workflow-block-parma-bg border border-workflow-block-parma-bg hover:border-gray-200',
|
||||
!isInWorkflow && (disabled ? 'border-text-warning bg-state-warning-hover ring-text-warning' : 'border-util-colors-indigo-indigo-600 bg-state-accent-hover ring-util-colors-indigo-indigo-600'),
|
||||
isInWorkflow && 'border border-workflow-block-parma-bg bg-workflow-block-parma-bg pr-[30px] hover:border-gray-200',
|
||||
)}
|
||||
>
|
||||
{
|
||||
currentProvider && (
|
||||
<ModelIcon
|
||||
className='mr-1.5 !w-5 !h-5'
|
||||
className='mr-1.5 !h-5 !w-5'
|
||||
provider={currentProvider}
|
||||
modelName={currentModel?.model}
|
||||
/>
|
||||
@@ -62,7 +62,7 @@ const Trigger: FC<TriggerProps> = ({
|
||||
{
|
||||
!currentProvider && (
|
||||
<ModelIcon
|
||||
className='mr-1.5 !w-5 !h-5'
|
||||
className='mr-1.5 !h-5 !w-5'
|
||||
provider={modelProviders.find(item => item.provider === providerName)}
|
||||
modelName={modelId}
|
||||
/>
|
||||
@@ -80,7 +80,7 @@ const Trigger: FC<TriggerProps> = ({
|
||||
}
|
||||
{
|
||||
!currentModel && (
|
||||
<div className='mr-1 text-[13px] font-medium text-text-primary truncate'>
|
||||
<div className='mr-1 truncate text-[13px] font-medium text-text-primary'>
|
||||
{modelId}
|
||||
</div>
|
||||
)
|
||||
@@ -97,14 +97,14 @@ const Trigger: FC<TriggerProps> = ({
|
||||
: ''
|
||||
}
|
||||
>
|
||||
<AlertTriangle className='w-4 h-4 text-[#F79009]' />
|
||||
<AlertTriangle className='h-4 w-4 text-[#F79009]' />
|
||||
</Tooltip>
|
||||
)
|
||||
: (
|
||||
<SlidersH className={cn(!isInWorkflow ? 'text-indigo-600' : 'text-text-tertiary', 'shrink-0 w-4 h-4')} />
|
||||
<SlidersH className={cn(!isInWorkflow ? 'text-indigo-600' : 'text-text-tertiary', 'h-4 w-4 shrink-0')} />
|
||||
)
|
||||
}
|
||||
{isInWorkflow && (<RiArrowDownSLine className='absolute top-[9px] right-2 w-3.5 h-3.5 text-text-tertiary' />)}
|
||||
{isInWorkflow && (<RiArrowDownSLine className='absolute right-2 top-[9px] h-3.5 w-3.5 text-text-tertiary' />)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -26,23 +26,23 @@ const ModelTrigger: FC<ModelTriggerProps> = ({
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn('group flex flex-grow box-content items-center p-[3px] pl-1 h-8 gap-1 rounded-lg bg-components-input-bg-disabled cursor-pointer', className)}
|
||||
className={cn('group box-content flex h-8 grow cursor-pointer items-center gap-1 rounded-lg bg-components-input-bg-disabled p-[3px] pl-1', className)}
|
||||
>
|
||||
<div className={cn('flex items-center w-full', contentClassName)}>
|
||||
<div className='flex items-center py-[1px] gap-1 min-w-0 flex-1'>
|
||||
<div className={cn('flex w-full items-center', contentClassName)}>
|
||||
<div className='flex min-w-0 flex-1 items-center gap-1 py-[1px]'>
|
||||
<ModelIcon
|
||||
className="w-4 h-4"
|
||||
className="h-4 w-4"
|
||||
provider={currentProvider}
|
||||
modelName={modelName}
|
||||
/>
|
||||
<div className='system-sm-regular text-components-input-text-filled truncate'>
|
||||
<div className='system-sm-regular truncate text-components-input-text-filled'>
|
||||
{modelName}
|
||||
</div>
|
||||
</div>
|
||||
<div className='shrink-0 flex items-center justify-center'>
|
||||
<div className='flex shrink-0 items-center justify-center'>
|
||||
{showWarnIcon && (
|
||||
<Tooltip popupContent={t('common.modelProvider.deprecated')}>
|
||||
<AlertTriangle className='w-4 h-4 text-text-warning-secondary' />
|
||||
<AlertTriangle className='h-4 w-4 text-text-warning-secondary' />
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -15,23 +15,23 @@ const ModelTrigger: FC<ModelTriggerProps> = ({
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'flex items-center p-1 gap-0.5 rounded-lg bg-components-input-bg-normal hover:bg-components-input-bg-hover cursor-pointer', open && 'bg-components-input-bg-hover',
|
||||
'flex cursor-pointer items-center gap-0.5 rounded-lg bg-components-input-bg-normal p-1 hover:bg-components-input-bg-hover', open && 'bg-components-input-bg-hover',
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<div className='grow flex items-center'>
|
||||
<div className='mr-1.5 flex items-center justify-center w-4 h-4 rounded-[5px] border border-dashed border-divider-regular'>
|
||||
<CubeOutline className='w-3 h-3 text-text-quaternary' />
|
||||
<div className='flex grow items-center'>
|
||||
<div className='mr-1.5 flex h-4 w-4 items-center justify-center rounded-[5px] border border-dashed border-divider-regular'>
|
||||
<CubeOutline className='h-3 w-3 text-text-quaternary' />
|
||||
</div>
|
||||
<div
|
||||
className='text-[13px] text-text-tertiary truncate'
|
||||
className='truncate text-[13px] text-text-tertiary'
|
||||
title='Configure model'
|
||||
>
|
||||
{t('plugin.detailPanel.configureModel')}
|
||||
</div>
|
||||
</div>
|
||||
<div className='shrink-0 flex items-center justify-center w-4 h-4'>
|
||||
<RiEqualizer2Line className='w-3.5 h-3.5 text-text-tertiary' />
|
||||
<div className='flex h-4 w-4 shrink-0 items-center justify-center'>
|
||||
<RiEqualizer2Line className='h-3.5 w-3.5 text-text-tertiary' />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -68,8 +68,8 @@ const FeatureIcon: FC<FeatureIconProps> = ({
|
||||
popupContent={t('common.modelProvider.featureSupported', { feature: ModelFeatureTextEnum.vision })}
|
||||
>
|
||||
<div className='inline-block cursor-help'>
|
||||
<ModelBadge className={`!px-0 w-[18px] justify-center text-text-tertiary ${className}`}>
|
||||
<MagicEyes className='w-3 h-3' />
|
||||
<ModelBadge className={`w-[18px] justify-center !px-0 text-text-tertiary ${className}`}>
|
||||
<MagicEyes className='h-3 w-3' />
|
||||
</ModelBadge>
|
||||
</div>
|
||||
</Tooltip>
|
||||
@@ -82,8 +82,8 @@ const FeatureIcon: FC<FeatureIconProps> = ({
|
||||
popupContent={t('common.modelProvider.featureSupported', { feature: ModelFeatureTextEnum.document })}
|
||||
>
|
||||
<div className='inline-block cursor-help'>
|
||||
<ModelBadge className={`!px-0 w-[18px] justify-center text-text-tertiary ${className}`}>
|
||||
<DocumentSupportIcon className='w-3 h-3' />
|
||||
<ModelBadge className={`w-[18px] justify-center !px-0 text-text-tertiary ${className}`}>
|
||||
<DocumentSupportIcon className='h-3 w-3' />
|
||||
</ModelBadge>
|
||||
</div>
|
||||
</Tooltip>
|
||||
@@ -96,8 +96,8 @@ const FeatureIcon: FC<FeatureIconProps> = ({
|
||||
popupContent={t('common.modelProvider.featureSupported', { feature: ModelFeatureTextEnum.audio })}
|
||||
>
|
||||
<div className='inline-block cursor-help'>
|
||||
<ModelBadge className={`!px-0 w-[18px] justify-center text-text-tertiary ${className}`}>
|
||||
<AudioSupportIcon className='w-3 h-3' />
|
||||
<ModelBadge className={`w-[18px] justify-center !px-0 text-text-tertiary ${className}`}>
|
||||
<AudioSupportIcon className='h-3 w-3' />
|
||||
</ModelBadge>
|
||||
</div>
|
||||
</Tooltip>
|
||||
@@ -110,8 +110,8 @@ const FeatureIcon: FC<FeatureIconProps> = ({
|
||||
popupContent={t('common.modelProvider.featureSupported', { feature: ModelFeatureTextEnum.video })}
|
||||
>
|
||||
<div className='inline-block cursor-help'>
|
||||
<ModelBadge className={`!px-0 w-[18px] justify-center text-text-tertiary ${className}`}>
|
||||
<VideoSupportIcon className='w-3 h-3' />
|
||||
<ModelBadge className={`w-[18px] justify-center !px-0 text-text-tertiary ${className}`}>
|
||||
<VideoSupportIcon className='h-3 w-3' />
|
||||
</ModelBadge>
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
||||
@@ -34,8 +34,8 @@ const ModelTrigger: FC<ModelTriggerProps> = ({
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'group flex items-center p-1 h-8 gap-0.5 rounded-lg bg-components-input-bg-normal',
|
||||
!readonly && 'hover:bg-components-input-bg-hover cursor-pointer',
|
||||
'group flex h-8 items-center gap-0.5 rounded-lg bg-components-input-bg-normal p-1',
|
||||
!readonly && 'cursor-pointer hover:bg-components-input-bg-hover',
|
||||
open && 'bg-components-input-bg-hover',
|
||||
model.status !== ModelStatusEnum.active && 'bg-components-input-bg-disabled hover:bg-components-input-bg-disabled',
|
||||
className,
|
||||
@@ -46,7 +46,7 @@ const ModelTrigger: FC<ModelTriggerProps> = ({
|
||||
provider={provider}
|
||||
modelName={model.model}
|
||||
/>
|
||||
<div className='flex px-1 py-[3px] items-center gap-1 grow truncate'>
|
||||
<div className='flex grow items-center gap-1 truncate px-1 py-[3px]'>
|
||||
<ModelName
|
||||
className='grow'
|
||||
modelItem={model}
|
||||
@@ -54,17 +54,17 @@ const ModelTrigger: FC<ModelTriggerProps> = ({
|
||||
showFeatures
|
||||
/>
|
||||
{!readonly && (
|
||||
<div className='shrink-0 flex items-center justify-center w-4 h-4'>
|
||||
<div className='flex h-4 w-4 shrink-0 items-center justify-center'>
|
||||
{
|
||||
model.status !== ModelStatusEnum.active
|
||||
? (
|
||||
<Tooltip popupContent={MODEL_STATUS_TEXT[model.status][language]}>
|
||||
<AlertTriangle className='w-4 h-4 text-text-warning-secondary' />
|
||||
<AlertTriangle className='h-4 w-4 text-text-warning-secondary' />
|
||||
</Tooltip>
|
||||
)
|
||||
: (
|
||||
<RiArrowDownSLine
|
||||
className='w-3.5 h-3.5 text-text-tertiary'
|
||||
className='h-3.5 w-3.5 text-text-tertiary'
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ const PopupItem: FC<PopupItemProps> = ({
|
||||
|
||||
return (
|
||||
<div className='mb-1'>
|
||||
<div className='flex items-center px-3 h-[22px] text-xs font-medium text-text-tertiary'>
|
||||
<div className='flex h-[22px] items-center px-3 text-xs font-medium text-text-tertiary'>
|
||||
{model.label[language] || model.label.en_US}
|
||||
</div>
|
||||
{
|
||||
@@ -93,11 +93,11 @@ const PopupItem: FC<PopupItemProps> = ({
|
||||
<div className='flex flex-col gap-1'>
|
||||
<div className='flex flex-col items-start gap-2'>
|
||||
<ModelIcon
|
||||
className={cn('shrink-0 w-5 h-5')}
|
||||
className={cn('h-5 w-5 shrink-0')}
|
||||
provider={model}
|
||||
modelName={modelItem.model}
|
||||
/>
|
||||
<div className='text-text-primary system-md-medium text-wrap break-words'>{modelItem.label[language] || modelItem.label.en_US}</div>
|
||||
<div className='system-md-medium text-wrap break-words text-text-primary'>{modelItem.label[language] || modelItem.label.en_US}</div>
|
||||
</div>
|
||||
{/* {currentProvider?.description && (
|
||||
<div className='text-text-tertiary system-xs-regular'>{currentProvider?.description?.[language] || currentProvider?.description?.en_US}</div>
|
||||
@@ -121,29 +121,29 @@ const PopupItem: FC<PopupItemProps> = ({
|
||||
</div>
|
||||
{modelItem.model_type === ModelTypeEnum.textGeneration && modelItem.features?.some(feature => [ModelFeatureEnum.vision, ModelFeatureEnum.audio, ModelFeatureEnum.video, ModelFeatureEnum.document].includes(feature)) && (
|
||||
<div className='pt-2'>
|
||||
<div className='mb-1 text-text-tertiary system-2xs-medium-uppercase'>{t('common.model.capabilities')}</div>
|
||||
<div className='system-2xs-medium-uppercase mb-1 text-text-tertiary'>{t('common.model.capabilities')}</div>
|
||||
<div className='flex flex-wrap gap-1'>
|
||||
{modelItem.features?.includes(ModelFeatureEnum.vision) && (
|
||||
<ModelBadge>
|
||||
<RiImageCircleAiLine className='w-3.5 h-3.5 mr-0.5' />
|
||||
<RiImageCircleAiLine className='mr-0.5 h-3.5 w-3.5' />
|
||||
<span>{ModelFeatureTextEnum.vision}</span>
|
||||
</ModelBadge>
|
||||
)}
|
||||
{modelItem.features?.includes(ModelFeatureEnum.audio) && (
|
||||
<ModelBadge>
|
||||
<RiVoiceAiFill className='w-3.5 h-3.5 mr-0.5' />
|
||||
<RiVoiceAiFill className='mr-0.5 h-3.5 w-3.5' />
|
||||
<span>{ModelFeatureTextEnum.audio}</span>
|
||||
</ModelBadge>
|
||||
)}
|
||||
{modelItem.features?.includes(ModelFeatureEnum.video) && (
|
||||
<ModelBadge>
|
||||
<RiFilmAiLine className='w-3.5 h-3.5 mr-0.5' />
|
||||
<RiFilmAiLine className='mr-0.5 h-3.5 w-3.5' />
|
||||
<span>{ModelFeatureTextEnum.video}</span>
|
||||
</ModelBadge>
|
||||
)}
|
||||
{modelItem.features?.includes(ModelFeatureEnum.document) && (
|
||||
<ModelBadge>
|
||||
<RiFileTextLine className='w-3.5 h-3.5 mr-0.5' />
|
||||
<RiFileTextLine className='mr-0.5 h-3.5 w-3.5' />
|
||||
<span>{ModelFeatureTextEnum.document}</span>
|
||||
</ModelBadge>
|
||||
)}
|
||||
@@ -155,29 +155,29 @@ const PopupItem: FC<PopupItemProps> = ({
|
||||
>
|
||||
<div
|
||||
key={modelItem.model}
|
||||
className={cn('group relative flex items-center px-3 py-1.5 h-8 rounded-lg gap-1', modelItem.status === ModelStatusEnum.active ? 'cursor-pointer hover:bg-state-base-hover' : 'cursor-not-allowed hover:bg-state-base-hover-alt')}
|
||||
className={cn('group relative flex h-8 items-center gap-1 rounded-lg px-3 py-1.5', modelItem.status === ModelStatusEnum.active ? 'cursor-pointer hover:bg-state-base-hover' : 'cursor-not-allowed hover:bg-state-base-hover-alt')}
|
||||
onClick={() => handleSelect(model.provider, modelItem)}
|
||||
>
|
||||
<div className='flex items-center gap-2'>
|
||||
<ModelIcon
|
||||
className={cn('shrink-0 w-5 h-5')}
|
||||
className={cn('h-5 w-5 shrink-0')}
|
||||
provider={model}
|
||||
modelName={modelItem.model}
|
||||
/>
|
||||
<ModelName
|
||||
className={cn('text-text-secondary system-sm-medium', modelItem.status !== ModelStatusEnum.active && 'opacity-60')}
|
||||
className={cn('system-sm-medium text-text-secondary', modelItem.status !== ModelStatusEnum.active && 'opacity-60')}
|
||||
modelItem={modelItem}
|
||||
/>
|
||||
</div>
|
||||
{
|
||||
defaultModel?.model === modelItem.model && defaultModel.provider === currentProvider.provider && (
|
||||
<Check className='shrink-0 w-4 h-4 text-text-accent' />
|
||||
<Check className='h-4 w-4 shrink-0 text-text-accent' />
|
||||
)
|
||||
}
|
||||
{
|
||||
modelItem.status === ModelStatusEnum.noConfigure && (
|
||||
<div
|
||||
className='hidden group-hover:block text-xs font-medium text-text-accent cursor-pointer'
|
||||
className='hidden cursor-pointer text-xs font-medium text-text-accent group-hover:block'
|
||||
onClick={handleOpenModelModal}
|
||||
>
|
||||
{t('common.operation.add').toLocaleUpperCase()}
|
||||
|
||||
@@ -59,20 +59,20 @@ const Popup: FC<PopupProps> = ({
|
||||
}, [language, modelList, scopeFeatures, searchText])
|
||||
|
||||
return (
|
||||
<div className='w-[320px] max-h-[480px] rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg overflow-y-auto'>
|
||||
<div className='sticky top-0 pl-3 pt-3 pr-2 pb-1 bg-components-panel-bg z-10'>
|
||||
<div className='max-h-[480px] w-[320px] overflow-y-auto rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg'>
|
||||
<div className='sticky top-0 z-10 bg-components-panel-bg pb-1 pl-3 pr-2 pt-3'>
|
||||
<div className={`
|
||||
flex items-center pl-[9px] pr-[10px] h-8 rounded-lg border
|
||||
${searchText ? 'bg-components-input-bg-active border-components-input-border-active shadow-xs' : 'bg-components-input-bg-normal border-transparent'}
|
||||
flex h-8 items-center rounded-lg border pl-[9px] pr-[10px]
|
||||
${searchText ? 'border-components-input-border-active bg-components-input-bg-active shadow-xs' : 'border-transparent bg-components-input-bg-normal'}
|
||||
`}>
|
||||
<RiSearchLine
|
||||
className={`
|
||||
shrink-0 mr-[7px] w-[14px] h-[14px]
|
||||
mr-[7px] h-[14px] w-[14px] shrink-0
|
||||
${searchText ? 'text-text-tertiary' : 'text-text-quaternary'}
|
||||
`}
|
||||
/>
|
||||
<input
|
||||
className='block grow h-[18px] text-[13px] text-text-primary appearance-none outline-none bg-transparent'
|
||||
className='block h-[18px] grow appearance-none bg-transparent text-[13px] text-text-primary outline-none'
|
||||
placeholder='Search model'
|
||||
value={searchText}
|
||||
onChange={e => setSearchText(e.target.value)}
|
||||
@@ -80,7 +80,7 @@ const Popup: FC<PopupProps> = ({
|
||||
{
|
||||
searchText && (
|
||||
<XCircle
|
||||
className='shrink-0 ml-1.5 w-[14px] h-[14px] text-text-quaternary cursor-pointer'
|
||||
className='ml-1.5 h-[14px] w-[14px] shrink-0 cursor-pointer text-text-quaternary'
|
||||
onClick={() => setSearchText('')}
|
||||
/>
|
||||
)
|
||||
@@ -100,18 +100,18 @@ const Popup: FC<PopupProps> = ({
|
||||
}
|
||||
{
|
||||
!filteredModelList.length && (
|
||||
<div className='px-3 py-1.5 leading-[18px] text-center text-xs text-text-tertiary break-all'>
|
||||
<div className='break-all px-3 py-1.5 text-center text-xs leading-[18px] text-text-tertiary'>
|
||||
{`No model found for “${searchText}”`}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div className='sticky bottom-0 px-4 py-2 flex items-center border-t border-divider-subtle cursor-pointer text-text-accent-light-mode-only bg-components-panel-bg rounded-b-lg' onClick={() => {
|
||||
<div className='sticky bottom-0 flex cursor-pointer items-center rounded-b-lg border-t border-divider-subtle bg-components-panel-bg px-4 py-2 text-text-accent-light-mode-only' onClick={() => {
|
||||
onHide()
|
||||
setShowAccountSettingModal({ payload: 'provider' })
|
||||
}}>
|
||||
<span className='system-xs-medium'>{t('common.model.settingsLink')}</span>
|
||||
<RiArrowRightUpLine className='ml-0.5 w-3 h-3' />
|
||||
<RiArrowRightUpLine className='ml-0.5 h-3 w-3' />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -15,10 +15,10 @@ const AddModelButton: FC<AddModelButtonProps> = ({
|
||||
|
||||
return (
|
||||
<span
|
||||
className={cn('shrink-0 flex items-center px-1.5 h-6 text-text-tertiary system-xs-medium cursor-pointer hover:bg-components-button-ghost-bg-hover hover:text-components-button-ghost-text rounded-md', className)}
|
||||
className={cn('system-xs-medium flex h-6 shrink-0 cursor-pointer items-center rounded-md px-1.5 text-text-tertiary hover:bg-components-button-ghost-bg-hover hover:text-components-button-ghost-text', className)}
|
||||
onClick={onClick}
|
||||
>
|
||||
<PlusCircle className='mr-1 w-3 h-3' />
|
||||
<PlusCircle className='mr-1 h-3 w-3' />
|
||||
{t('common.modelProvider.addModel')}
|
||||
</span>
|
||||
)
|
||||
|
||||
@@ -55,7 +55,7 @@ const CooldownTimer = ({ secondsRemaining, onFinish }: CooldownTimerProps) => {
|
||||
return displayTime
|
||||
? (
|
||||
<Tooltip popupContent={t('common.modelProvider.apiKeyRateLimit', { seconds: displayTime })}>
|
||||
<SimplePieChart percentage={Math.round(displayTime / 60 * 100)} className='w-3 h-3' />
|
||||
<SimplePieChart percentage={Math.round(displayTime / 60 * 100)} className='h-3 w-3' />
|
||||
</Tooltip>
|
||||
)
|
||||
: null
|
||||
|
||||
@@ -66,8 +66,8 @@ const CredentialPanel: FC<CredentialPanelProps> = ({
|
||||
<>
|
||||
{
|
||||
provider.provider_credential_schema && (
|
||||
<div className='shrink-0 relative ml-1 p-1 w-[112px] rounded-lg bg-white/[0.18] border-[0.5px] border-components-panel-border'>
|
||||
<div className='flex items-center justify-between mb-1 pt-1 pl-2 pr-[7px] h-5 system-xs-medium-uppercase text-text-tertiary'>
|
||||
<div className='relative ml-1 w-[112px] shrink-0 rounded-lg border-[0.5px] border-components-panel-border bg-white/[0.18] p-1'>
|
||||
<div className='system-xs-medium-uppercase mb-1 flex h-5 items-center justify-between pl-2 pr-[7px] pt-1 text-text-tertiary'>
|
||||
API-KEY
|
||||
<Indicator color={isCustomConfigured ? 'green' : 'red'} />
|
||||
</div>
|
||||
@@ -77,7 +77,7 @@ const CredentialPanel: FC<CredentialPanelProps> = ({
|
||||
size='small'
|
||||
onClick={onSetup}
|
||||
>
|
||||
<RiEqualizer2Line className='mr-1 w-3.5 h-3.5' />
|
||||
<RiEqualizer2Line className='mr-1 h-3.5 w-3.5' />
|
||||
{t('common.operation.setup')}
|
||||
</Button>
|
||||
{
|
||||
|
||||
@@ -83,13 +83,13 @@ const ProviderAddedCard: FC<ProviderAddedCardProps> = ({
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'mb-2 rounded-xl border-[0.5px] border-divider-regular shadow-xs bg-third-party-model-bg-default',
|
||||
'mb-2 rounded-xl border-[0.5px] border-divider-regular bg-third-party-model-bg-default shadow-xs',
|
||||
provider.provider === 'langgenius/openai/openai' && 'bg-third-party-model-bg-openai',
|
||||
provider.provider === 'langgenius/anthropic/anthropic' && 'bg-third-party-model-bg-anthropic',
|
||||
)}
|
||||
>
|
||||
<div className='flex pl-3 py-2 pr-2 rounded-t-xl'>
|
||||
<div className='grow px-1 pt-1 pb-0.5'>
|
||||
<div className='flex rounded-t-xl py-2 pl-3 pr-2'>
|
||||
<div className='grow px-1 pb-0.5 pt-1'>
|
||||
<ProviderIcon
|
||||
className='mb-2'
|
||||
provider={provider}
|
||||
@@ -122,19 +122,19 @@ const ProviderAddedCard: FC<ProviderAddedCardProps> = ({
|
||||
</div>
|
||||
{
|
||||
collapsed && (
|
||||
<div className='group flex items-center justify-between pl-2 py-1.5 pr-[11px] border-t border-t-divider-subtle text-text-tertiary system-xs-medium'>
|
||||
<div className='system-xs-medium group flex items-center justify-between border-t border-t-divider-subtle py-1.5 pl-2 pr-[11px] text-text-tertiary'>
|
||||
{(showQuota || !notConfigured) && (
|
||||
<>
|
||||
<div className='group-hover:hidden flex items-center pl-1 pr-1.5 h-6 leading-6'>
|
||||
<div className='flex h-6 items-center pl-1 pr-1.5 leading-6 group-hover:hidden'>
|
||||
{
|
||||
hasModelList
|
||||
? t('common.modelProvider.modelsNum', { num: modelList.length })
|
||||
: t('common.modelProvider.showModels')
|
||||
}
|
||||
{!loading && <RiArrowRightSLine className='w-4 h-4' />}
|
||||
{!loading && <RiArrowRightSLine className='h-4 w-4' />}
|
||||
</div>
|
||||
<div
|
||||
className='hidden group-hover:flex items-center pl-1 pr-1.5 h-6 rounded-lg hover:bg-components-button-ghost-bg-hover cursor-pointer'
|
||||
className='hidden h-6 cursor-pointer items-center rounded-lg pl-1 pr-1.5 hover:bg-components-button-ghost-bg-hover group-hover:flex'
|
||||
onClick={handleOpenModelList}
|
||||
>
|
||||
{
|
||||
@@ -142,19 +142,19 @@ const ProviderAddedCard: FC<ProviderAddedCardProps> = ({
|
||||
? t('common.modelProvider.showModelsNum', { num: modelList.length })
|
||||
: t('common.modelProvider.showModels')
|
||||
}
|
||||
{!loading && <RiArrowRightSLine className='w-4 h-4' />}
|
||||
{!loading && <RiArrowRightSLine className='h-4 w-4' />}
|
||||
{
|
||||
loading && (
|
||||
<RiLoader2Line className='ml-0.5 animate-spin w-3 h-3' />
|
||||
<RiLoader2Line className='ml-0.5 h-3 w-3 animate-spin' />
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{!showQuota && notConfigured && (
|
||||
<div className='flex items-center pl-1 pr-1.5 h-6'>
|
||||
<RiInformation2Fill className='mr-1 w-4 h-4 text-text-accent' />
|
||||
<span className='text-text-secondary system-xs-medium'>{t('common.modelProvider.configureTip')}</span>
|
||||
<div className='flex h-6 items-center pl-1 pr-1.5'>
|
||||
<RiInformation2Fill className='mr-1 h-4 w-4 text-text-accent' />
|
||||
<span className='system-xs-medium text-text-secondary'>{t('common.modelProvider.configureTip')}</span>
|
||||
</div>
|
||||
)}
|
||||
{
|
||||
|
||||
@@ -54,25 +54,25 @@ const ModelListItem = ({ model, provider, isConfigurable, onConfig, onModifyLoad
|
||||
)}
|
||||
>
|
||||
<ModelIcon
|
||||
className='shrink-0 mr-2'
|
||||
className='mr-2 shrink-0'
|
||||
provider={provider}
|
||||
modelName={model.model}
|
||||
/>
|
||||
<ModelName
|
||||
className='grow system-md-regular text-text-secondary'
|
||||
className='system-md-regular grow text-text-secondary'
|
||||
modelItem={model}
|
||||
showModelType
|
||||
showMode
|
||||
showContextSize
|
||||
>
|
||||
{modelLoadBalancingEnabled && !model.deprecated && model.load_balancing_enabled && (
|
||||
<ModelBadge className='ml-1 uppercase text-text-accent-secondary border-text-accent-secondary'>
|
||||
<Balance className='w-3 h-3 mr-0.5' />
|
||||
<ModelBadge className='ml-1 border-text-accent-secondary uppercase text-text-accent-secondary'>
|
||||
<Balance className='mr-0.5 h-3 w-3' />
|
||||
{t('common.modelProvider.loadBalancingHeadline')}
|
||||
</ModelBadge>
|
||||
)}
|
||||
</ModelName>
|
||||
<div className='shrink-0 flex items-center'>
|
||||
<div className='flex shrink-0 items-center'>
|
||||
{
|
||||
model.fetch_from === ConfigurationMethodEnum.customizableModel
|
||||
? (isCurrentWorkspaceManager && (
|
||||
@@ -81,7 +81,7 @@ const ModelListItem = ({ model, provider, isConfigurable, onConfig, onModifyLoad
|
||||
className='hidden group-hover:flex'
|
||||
onClick={() => onConfig({ __model_name: model.model, __model_type: model.model_type })}
|
||||
>
|
||||
<Settings01 className='mr-1 w-3.5 h-3.5' />
|
||||
<Settings01 className='mr-1 h-3.5 w-3.5' />
|
||||
{t('common.modelProvider.config')}
|
||||
</Button>
|
||||
))
|
||||
@@ -89,10 +89,10 @@ const ModelListItem = ({ model, provider, isConfigurable, onConfig, onModifyLoad
|
||||
? (
|
||||
<Button
|
||||
size='small'
|
||||
className='opacity-0 group-hover:opacity-100 transition-opacity'
|
||||
className='opacity-0 transition-opacity group-hover:opacity-100'
|
||||
onClick={() => onModifyLoadBalancing?.(model)}
|
||||
>
|
||||
<Balance className='mr-1 w-3.5 h-3.5' />
|
||||
<Balance className='mr-1 h-3.5 w-3.5' />
|
||||
{t('common.modelProvider.configLoadBalancing')}
|
||||
</Button>
|
||||
)
|
||||
|
||||
@@ -49,20 +49,20 @@ const ModelList: FC<ModelListProps> = ({
|
||||
}, [onChange, provider, setShowModelLoadBalancingModal])
|
||||
|
||||
return (
|
||||
<div className='px-2 pb-2 rounded-b-xl'>
|
||||
<div className='py-1 bg-components-panel-bg rounded-lg'>
|
||||
<div className='rounded-b-xl px-2 pb-2'>
|
||||
<div className='rounded-lg bg-components-panel-bg py-1'>
|
||||
<div className='flex items-center pl-1 pr-[3px]'>
|
||||
<span className='group shrink-0 flex items-center mr-2'>
|
||||
<span className='group-hover:hidden inline-flex items-center pl-1 pr-1.5 h-6 system-xs-medium text-text-tertiary'>
|
||||
<span className='group mr-2 flex shrink-0 items-center'>
|
||||
<span className='system-xs-medium inline-flex h-6 items-center pl-1 pr-1.5 text-text-tertiary group-hover:hidden'>
|
||||
{t('common.modelProvider.modelsNum', { num: models.length })}
|
||||
<RiArrowRightSLine className='mr-0.5 w-4 h-4 rotate-90' />
|
||||
<RiArrowRightSLine className='mr-0.5 h-4 w-4 rotate-90' />
|
||||
</span>
|
||||
<span
|
||||
className='hidden group-hover:inline-flex items-center pl-1 pr-1.5 h-6 system-xs-medium text-text-tertiary bg-state-base-hover cursor-pointer rounded-lg'
|
||||
className='system-xs-medium hidden h-6 cursor-pointer items-center rounded-lg bg-state-base-hover pl-1 pr-1.5 text-text-tertiary group-hover:inline-flex'
|
||||
onClick={() => onCollapse()}
|
||||
>
|
||||
{t('common.modelProvider.modelsNum', { num: models.length })}
|
||||
<RiArrowRightSLine className='mr-0.5 w-4 h-4 rotate-90' />
|
||||
<RiArrowRightSLine className='mr-0.5 h-4 w-4 rotate-90' />
|
||||
</span>
|
||||
</span>
|
||||
{/* {
|
||||
@@ -74,7 +74,7 @@ const ModelList: FC<ModelListProps> = ({
|
||||
} */}
|
||||
{
|
||||
isConfigurable && isCurrentWorkspaceManager && (
|
||||
<div className='grow flex justify-end'>
|
||||
<div className='flex grow justify-end'>
|
||||
<AddModelButton onClick={() => onConfig()} />
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -152,9 +152,9 @@ const ModelLoadBalancingConfigs = ({
|
||||
)}
|
||||
onClick={(!withSwitch && !draftConfig.enabled) ? () => toggleModalBalancing(true) : undefined}
|
||||
>
|
||||
<div className='flex items-center px-[15px] py-3 gap-2 select-none'>
|
||||
<div className='grow-0 shrink-0 flex items-center justify-center w-8 h-8 text-util-colors-blue-blue-600 bg-util-colors-indigo-indigo-50 border border-util-colors-indigo-indigo-100 rounded-lg'>
|
||||
<Balance className='w-4 h-4' />
|
||||
<div className='flex select-none items-center gap-2 px-[15px] py-3'>
|
||||
<div className='flex h-8 w-8 shrink-0 grow-0 items-center justify-center rounded-lg border border-util-colors-indigo-indigo-100 bg-util-colors-indigo-indigo-50 text-util-colors-blue-blue-600'>
|
||||
<Balance className='h-4 w-4' />
|
||||
</div>
|
||||
<div className='grow'>
|
||||
<div className='flex items-center gap-1 text-sm text-text-primary'>
|
||||
@@ -184,9 +184,9 @@ const ModelLoadBalancingConfigs = ({
|
||||
{draftConfig.configs.map((config, index) => {
|
||||
const isProviderManaged = config.name === '__inherit__'
|
||||
return (
|
||||
<div key={config.id || index} className='group flex items-center px-3 h-10 bg-components-panel-on-panel-item-bg border border-components-panel-border rounded-lg shadow-xs'>
|
||||
<div className='grow flex items-center'>
|
||||
<div className='flex items-center justify-center mr-2 w-3 h-3'>
|
||||
<div key={config.id || index} className='group flex h-10 items-center rounded-lg border border-components-panel-border bg-components-panel-on-panel-item-bg px-3 shadow-xs'>
|
||||
<div className='flex grow items-center'>
|
||||
<div className='mr-2 flex h-3 w-3 items-center justify-center'>
|
||||
{(config.in_cooldown && Boolean(config.ttl))
|
||||
? (
|
||||
<CooldownTimer secondsRemaining={config.ttl} onFinish={() => clearCountdown(index)} />
|
||||
@@ -197,11 +197,11 @@ const ModelLoadBalancingConfigs = ({
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
<div className='text-[13px] mr-1'>
|
||||
<div className='mr-1 text-[13px]'>
|
||||
{isProviderManaged ? t('common.modelProvider.defaultConfig') : config.name}
|
||||
</div>
|
||||
{isProviderManaged && (
|
||||
<span className='px-1 text-2xs uppercase text-text-tertiary border border-divider-regular rounded-[5px]'>{t('common.modelProvider.providerManaged')}</span>
|
||||
<span className='rounded-[5px] border border-divider-regular px-1 text-2xs uppercase text-text-tertiary'>{t('common.modelProvider.providerManaged')}</span>
|
||||
)}
|
||||
</div>
|
||||
<div className='flex items-center gap-1'>
|
||||
@@ -209,16 +209,16 @@ const ModelLoadBalancingConfigs = ({
|
||||
<>
|
||||
<div className='flex items-center gap-1 opacity-0 transition-opacity group-hover:opacity-100'>
|
||||
<span
|
||||
className='flex items-center justify-center w-8 h-8 text-text-tertiary bg-components-button-secondary-bg rounded-lg transition-colors cursor-pointer hover:bg-components-button-secondary-bg-hover'
|
||||
className='flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg bg-components-button-secondary-bg text-text-tertiary transition-colors hover:bg-components-button-secondary-bg-hover'
|
||||
onClick={() => toggleEntryModal(index, config)}
|
||||
>
|
||||
<Edit02 className='w-4 h-4' />
|
||||
<Edit02 className='h-4 w-4' />
|
||||
</span>
|
||||
<span
|
||||
className='flex items-center justify-center w-8 h-8 text-text-tertiary bg-components-button-secondary-bg rounded-lg transition-colors cursor-pointer hover:bg-components-button-secondary-bg-hover'
|
||||
className='flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg bg-components-button-secondary-bg text-text-tertiary transition-colors hover:bg-components-button-secondary-bg-hover'
|
||||
onClick={() => updateConfigEntry(index, () => undefined)}
|
||||
>
|
||||
<RiDeleteBinLine className='w-4 h-4' />
|
||||
<RiDeleteBinLine className='h-4 w-4' />
|
||||
</span>
|
||||
<span className='mr-2 h-3 border-r border-r-divider-subtle' />
|
||||
</div>
|
||||
@@ -236,19 +236,19 @@ const ModelLoadBalancingConfigs = ({
|
||||
})}
|
||||
|
||||
<div
|
||||
className='flex items-center px-3 mt-1 h-8 text-[13px] font-medium text-primary-600'
|
||||
className='mt-1 flex h-8 items-center px-3 text-[13px] font-medium text-primary-600'
|
||||
onClick={() => toggleEntryModal()}
|
||||
>
|
||||
<div className='flex items-center cursor-pointer'>
|
||||
<Plus02 className='mr-2 w-3 h-3' />{t('common.modelProvider.addConfig')}
|
||||
<div className='flex cursor-pointer items-center'>
|
||||
<Plus02 className='mr-2 h-3 w-3' />{t('common.modelProvider.addConfig')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{
|
||||
draftConfig.enabled && draftConfig.configs.length < 2 && (
|
||||
<div className='flex items-center px-6 h-[34px] text-xs text-text-secondary bg-components-panel-bg border-t border-t-divider-subtle'>
|
||||
<AlertTriangle className='mr-1 w-3 h-3 text-[#f79009]' />
|
||||
<div className='flex h-[34px] items-center border-t border-t-divider-subtle bg-components-panel-bg px-6 text-xs text-text-secondary'>
|
||||
<AlertTriangle className='mr-1 h-3 w-3 text-[#f79009]' />
|
||||
{t('common.modelProvider.loadBalancingLeastKeyWarning')}
|
||||
</div>
|
||||
)
|
||||
@@ -257,7 +257,7 @@ const ModelLoadBalancingConfigs = ({
|
||||
|
||||
{!modelLoadBalancingEnabled && !IS_CE_EDITION && (
|
||||
<GridMask canvasClassName='!rounded-xl'>
|
||||
<div className='flex items-center justify-between mt-2 px-4 h-14 border-[0.5px] border-components-panel-border rounded-xl shadow-md'>
|
||||
<div className='mt-2 flex h-14 items-center justify-between rounded-xl border-[0.5px] border-components-panel-border px-4 shadow-md'>
|
||||
<div
|
||||
className={classNames('text-sm font-semibold leading-tight text-gradient', s.textGradient)}
|
||||
>
|
||||
|
||||
@@ -107,19 +107,19 @@ const ModelLoadBalancingModal = ({ provider, model, open = false, onClose, onSav
|
||||
<Modal
|
||||
isShow={Boolean(model) && open}
|
||||
onClose={onClose}
|
||||
className='max-w-none pt-8 px-8 w-[640px]'
|
||||
className='w-[640px] max-w-none px-8 pt-8'
|
||||
title={
|
||||
<div className='pb-3 font-semibold'>
|
||||
<div className='h-[30px]'>{t('common.modelProvider.configLoadBalancing')}</div>
|
||||
{Boolean(model) && (
|
||||
<div className='flex items-center h-5'>
|
||||
<div className='flex h-5 items-center'>
|
||||
<ModelIcon
|
||||
className='shrink-0 mr-2'
|
||||
className='mr-2 shrink-0'
|
||||
provider={provider}
|
||||
modelName={model!.model}
|
||||
/>
|
||||
<ModelName
|
||||
className='grow system-md-regular text-text-secondary'
|
||||
className='system-md-regular grow text-text-secondary'
|
||||
modelItem={model!}
|
||||
showModelType
|
||||
showMode
|
||||
@@ -142,8 +142,8 @@ const ModelLoadBalancingModal = ({ provider, model, open = false, onClose, onSav
|
||||
)}
|
||||
onClick={draftConfig.enabled ? () => toggleModalBalancing(false) : undefined}
|
||||
>
|
||||
<div className='flex items-center px-[15px] py-3 gap-2 select-none'>
|
||||
<div className='grow-0 shrink-0 flex items-center justify-center w-8 h-8 bg-components-card-bg border border-components-card-border rounded-lg'>
|
||||
<div className='flex select-none items-center gap-2 px-[15px] py-3'>
|
||||
<div className='flex h-8 w-8 shrink-0 grow-0 items-center justify-center rounded-lg border border-components-card-border bg-components-card-bg'>
|
||||
{Boolean(model) && (
|
||||
<ModelIcon className='shrink-0' provider={provider} modelName={model!.model} />
|
||||
)}
|
||||
@@ -168,7 +168,7 @@ const ModelLoadBalancingModal = ({ provider, model, open = false, onClose, onSav
|
||||
}} />
|
||||
</div>
|
||||
|
||||
<div className='flex items-center justify-end gap-2 mt-6'>
|
||||
<div className='mt-6 flex items-center justify-end gap-2'>
|
||||
<Button onClick={onClose}>{t('common.operation.cancel')}</Button>
|
||||
<Button
|
||||
variant='primary'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Fragment } from 'react'
|
||||
import type { FC } from 'react'
|
||||
import { Popover, Transition } from '@headlessui/react'
|
||||
import { Popover, PopoverButton, PopoverPanel, Transition } from '@headlessui/react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import {
|
||||
RiCheckLine,
|
||||
@@ -32,42 +32,42 @@ const Selector: FC<SelectorProps> = ({
|
||||
|
||||
return (
|
||||
<Popover className='relative'>
|
||||
<Popover.Button>
|
||||
<PopoverButton as='div'>
|
||||
{
|
||||
({ open }) => (
|
||||
<Button className={cn(
|
||||
'px-0 w-6 h-6 rounded-md',
|
||||
'h-6 w-6 rounded-md px-0',
|
||||
open && 'bg-components-button-secondary-bg-hover',
|
||||
)}>
|
||||
<RiMoreFill className='w-3 h-3' />
|
||||
<RiMoreFill className='h-3 w-3' />
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
</Popover.Button>
|
||||
</PopoverButton>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
leave='transition ease-in duration-100'
|
||||
leaveFrom='opacity-100'
|
||||
leaveTo='opacity-0'
|
||||
>
|
||||
<Popover.Panel className='absolute top-7 right-0 w-[144px] bg-components-panel-bg border-[0.5px] border-components-panel-border rounded-lg shadow-lg z-10'>
|
||||
<PopoverPanel className='absolute right-0 top-7 z-10 w-[144px] rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg'>
|
||||
<div className='p-1'>
|
||||
<div className='px-3 pt-2 pb-1 text-sm font-medium text-text-secondary'>{t('common.modelProvider.card.priorityUse')}</div>
|
||||
<div className='px-3 pb-1 pt-2 text-sm font-medium text-text-secondary'>{t('common.modelProvider.card.priorityUse')}</div>
|
||||
{
|
||||
options.map(option => (
|
||||
<Popover.Button as={Fragment} key={option.key}>
|
||||
<PopoverButton as={Fragment} key={option.key}>
|
||||
<div
|
||||
className='flex items-center justify-between px-3 h-9 text-sm text-text-secondary rounded-lg cursor-pointer hover:bg-components-panel-on-panel-item-bg-hover'
|
||||
className='flex h-9 cursor-pointer items-center justify-between rounded-lg px-3 text-sm text-text-secondary hover:bg-components-panel-on-panel-item-bg-hover'
|
||||
onClick={() => onSelect(option.key)}
|
||||
>
|
||||
<div className='grow'>{option.text}</div>
|
||||
{value === option.key && <RiCheckLine className='w-4 h-4 text-text-accent' />}
|
||||
{value === option.key && <RiCheckLine className='h-4 w-4 text-text-accent' />}
|
||||
</div>
|
||||
</Popover.Button>
|
||||
</PopoverButton>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</Popover.Panel>
|
||||
</PopoverPanel>
|
||||
</Transition>
|
||||
</Popover>
|
||||
)
|
||||
|
||||
@@ -9,8 +9,8 @@ const PriorityUseTip = () => {
|
||||
<Tooltip
|
||||
popupContent={t('common.modelProvider.priorityUsing') || ''}
|
||||
>
|
||||
<div className='absolute -right-[5px] -top-[5px] bg-util-colors-indigo-indigo-50 rounded-[5px] border-[0.5px] border-components-panel-border-subtle shadow-xs cursor-pointer'>
|
||||
<ChevronDownDouble className='rotate-180 w-3 h-3 text-util-colors-indigo-indigo-600' />
|
||||
<div className='absolute -right-[5px] -top-[5px] cursor-pointer rounded-[5px] border-[0.5px] border-components-panel-border-subtle bg-util-colors-indigo-indigo-50 shadow-xs'>
|
||||
<ChevronDownDouble className='h-3 w-3 rotate-180 text-util-colors-indigo-indigo-600' />
|
||||
</div>
|
||||
</Tooltip>
|
||||
)
|
||||
|
||||
@@ -28,8 +28,8 @@ const QuotaPanel: FC<QuotaPanelProps> = ({
|
||||
const openaiOrAnthropic = MODEL_PROVIDER_QUOTA_GET_PAID.includes(provider.provider)
|
||||
|
||||
return (
|
||||
<div className='group relative shrink-0 min-w-[112px] px-3 py-2 rounded-lg bg-white/[0.18] border-[0.5px] border-components-panel-border shadow-xs'>
|
||||
<div className='flex items-center mb-2 h-4 system-xs-medium-uppercase text-text-tertiary'>
|
||||
<div className='group relative min-w-[112px] shrink-0 rounded-lg border-[0.5px] border-components-panel-border bg-white/[0.18] px-3 py-2 shadow-xs'>
|
||||
<div className='system-xs-medium-uppercase mb-2 flex h-4 items-center text-text-tertiary'>
|
||||
{t('common.modelProvider.quota')}
|
||||
<Tooltip popupContent={
|
||||
openaiOrAnthropic
|
||||
@@ -40,8 +40,8 @@ const QuotaPanel: FC<QuotaPanelProps> = ({
|
||||
</div>
|
||||
{
|
||||
currentQuota && (
|
||||
<div className='flex items-center h-4 text-xs text-text-tertiary'>
|
||||
<span className='mr-0.5 system-md-semibold-uppercase text-text-secondary'>{formatNumber(Math.max((currentQuota?.quota_limit || 0) - (currentQuota?.quota_used || 0), 0))}</span>
|
||||
<div className='flex h-4 items-center text-xs text-text-tertiary'>
|
||||
<span className='system-md-semibold-uppercase mr-0.5 text-text-secondary'>{formatNumber(Math.max((currentQuota?.quota_limit || 0) - (currentQuota?.quota_used || 0), 0))}</span>
|
||||
{
|
||||
currentQuota?.quota_unit === QuotaUnitEnum.tokens && 'Tokens'
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ const ProviderIcon: FC<ProviderIconProps> = ({
|
||||
if (provider.provider === 'langgenius/anthropic/anthropic') {
|
||||
return (
|
||||
<div className='mb-2 py-[7px]'>
|
||||
{theme === Theme.dark && <AnthropicLight className='w-[90px] h-2.5' />}
|
||||
{theme === Theme.light && <AnthropicDark className='w-[90px] h-2.5' />}
|
||||
{theme === Theme.dark && <AnthropicLight className='h-2.5 w-[90px]' />}
|
||||
{theme === Theme.light && <AnthropicDark className='h-2.5 w-[90px]' />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -31,7 +31,7 @@ const ProviderIcon: FC<ProviderIconProps> = ({
|
||||
if (provider.provider === 'langgenius/openai/openai') {
|
||||
return (
|
||||
<div className='mb-2'>
|
||||
<Openai className='w-auto h-6 text-text-inverted-dimmed' />
|
||||
<Openai className='h-6 w-auto text-text-inverted-dimmed' />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -41,7 +41,7 @@ const ProviderIcon: FC<ProviderIconProps> = ({
|
||||
<img
|
||||
alt='provider-icon'
|
||||
src={renderI18nObject(provider.icon_small, language)}
|
||||
className='w-6 h-6'
|
||||
className='h-6 w-6'
|
||||
/>
|
||||
<div className='system-md-semibold text-text-primary'>
|
||||
{renderI18nObject(provider.label, language)}
|
||||
|
||||
@@ -135,14 +135,14 @@ const SystemModel: FC<SystemModelSelectorProps> = ({
|
||||
variant={notConfigured ? 'primary' : 'secondary'}
|
||||
size='small'
|
||||
>
|
||||
<RiEqualizer2Line className='mr-1 w-3.5 h-3.5' />
|
||||
<RiEqualizer2Line className='mr-1 h-3.5 w-3.5' />
|
||||
{t('common.modelProvider.systemModelSettings')}
|
||||
</Button>
|
||||
</PortalToFollowElemTrigger>
|
||||
<PortalToFollowElemContent className='z-[60]'>
|
||||
<div className='pt-4 w-[360px] rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xl'>
|
||||
<div className='w-[360px] rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg pt-4 shadow-xl'>
|
||||
<div className='px-6 py-1'>
|
||||
<div className='flex items-center h-8 text-[13px] font-medium text-text-primary'>
|
||||
<div className='flex h-8 items-center text-[13px] font-medium text-text-primary'>
|
||||
{t('common.modelProvider.systemReasoningModel.key')}
|
||||
<Tooltip
|
||||
popupContent={
|
||||
@@ -162,7 +162,7 @@ const SystemModel: FC<SystemModelSelectorProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className='px-6 py-1'>
|
||||
<div className='flex items-center h-8 text-[13px] font-medium text-text-primary'>
|
||||
<div className='flex h-8 items-center text-[13px] font-medium text-text-primary'>
|
||||
{t('common.modelProvider.embeddingModel.key')}
|
||||
<Tooltip
|
||||
popupContent={
|
||||
@@ -182,7 +182,7 @@ const SystemModel: FC<SystemModelSelectorProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className='px-6 py-1'>
|
||||
<div className='flex items-center h-8 text-[13px] font-medium text-text-primary'>
|
||||
<div className='flex h-8 items-center text-[13px] font-medium text-text-primary'>
|
||||
{t('common.modelProvider.rerankModel.key')}
|
||||
<Tooltip
|
||||
popupContent={
|
||||
@@ -202,7 +202,7 @@ const SystemModel: FC<SystemModelSelectorProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className='px-6 py-1'>
|
||||
<div className='flex items-center h-8 text-[13px] font-medium text-text-primary'>
|
||||
<div className='flex h-8 items-center text-[13px] font-medium text-text-primary'>
|
||||
{t('common.modelProvider.speechToTextModel.key')}
|
||||
<Tooltip
|
||||
popupContent={
|
||||
@@ -222,7 +222,7 @@ const SystemModel: FC<SystemModelSelectorProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className='px-6 py-1'>
|
||||
<div className='flex items-center h-8 text-[13px] font-medium text-text-primary'>
|
||||
<div className='flex h-8 items-center text-[13px] font-medium text-text-primary'>
|
||||
{t('common.modelProvider.ttsModel.key')}
|
||||
<Tooltip
|
||||
popupContent={
|
||||
|
||||
@@ -10,7 +10,7 @@ const PluginPage = () => {
|
||||
const { t } = useTranslation()
|
||||
const { data: plugins, mutate } = useSWR('/workspaces/current/tool-providers', fetchPluginProviders)
|
||||
|
||||
const Plugin_MAP: Record<string, (plugin: PluginProvider) => JSX.Element> = {
|
||||
const Plugin_MAP: Record<string, (plugin: PluginProvider) => React.JSX.Element> = {
|
||||
serpapi: (plugin: PluginProvider) => <SerpapiPlugin key='serpapi' plugin={plugin} onUpdate={() => mutate()} />,
|
||||
}
|
||||
|
||||
@@ -19,11 +19,11 @@ const PluginPage = () => {
|
||||
<div>
|
||||
{plugins?.map(plugin => Plugin_MAP[plugin.tool_name](plugin))}
|
||||
</div>
|
||||
<div className='fixed bottom-0 w-[472px] h-[42px] flex items-center bg-white text-xs text-gray-500'>
|
||||
<LockClosedIcon className='w-3 h-3 mr-1' />
|
||||
<div className='fixed bottom-0 flex h-[42px] w-[472px] items-center bg-white text-xs text-gray-500'>
|
||||
<LockClosedIcon className='mr-1 h-3 w-3' />
|
||||
{t('common.provider.encrypted.front')}
|
||||
<Link
|
||||
className='text-primary-600 mx-1'
|
||||
className='mx-1 text-primary-600'
|
||||
target='_blank' rel='noopener noreferrer'
|
||||
href='https://pycryptodome.readthedocs.io/en/latest/src/cipher/oaep.html'
|
||||
>
|
||||
|
||||
@@ -27,8 +27,8 @@ export default function AppBack({ curApp }: IAppBackProps) {
|
||||
>
|
||||
{
|
||||
(hovered && curApp)
|
||||
? <ArrowLeftIcon className='mr-1 w-[18px] h-[18px]' />
|
||||
: <Squares2X2Icon className='mr-1 w-[18px] h-[18px]' />
|
||||
? <ArrowLeftIcon className='mr-1 h-[18px] w-[18px]' />
|
||||
: <Squares2X2Icon className='mr-1 h-[18px] w-[18px]' />
|
||||
}
|
||||
{t('common.menus.apps')}
|
||||
</div>
|
||||
|
||||
@@ -117,8 +117,8 @@ const AppNav = () => {
|
||||
<>
|
||||
<Nav
|
||||
isApp
|
||||
icon={<RiRobot2Line className='w-4 h-4' />}
|
||||
activeIcon={<RiRobot2Fill className='w-4 h-4' />}
|
||||
icon={<RiRobot2Line className='h-4 w-4' />}
|
||||
activeIcon={<RiRobot2Fill className='h-4 w-4' />}
|
||||
text={t('common.menus.apps')}
|
||||
activeSegment={['apps', 'app']}
|
||||
link='/apps'
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Fragment, useState } from 'react'
|
||||
import { ChevronDownIcon, PlusIcon } from '@heroicons/react/24/solid'
|
||||
import { Menu, Transition } from '@headlessui/react'
|
||||
import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import Indicator from '../indicator'
|
||||
import type { AppDetailResponse } from '@/models/app'
|
||||
@@ -30,19 +30,19 @@ export default function AppSelector({ appItems, curApp }: IAppSelectorProps) {
|
||||
<div className="">
|
||||
<Menu as="div" className="relative inline-block text-left">
|
||||
<div>
|
||||
<Menu.Button
|
||||
<MenuButton
|
||||
className="
|
||||
inline-flex items-center w-full h-7 justify-center
|
||||
inline-flex h-7 w-full items-center justify-center
|
||||
rounded-[10px] pl-2 pr-2.5 text-[14px] font-semibold
|
||||
text-[#1C64F2] hover:bg-[#EBF5FF]
|
||||
"
|
||||
>
|
||||
{curApp?.name}
|
||||
<ChevronDownIcon
|
||||
className="w-3 h-3 ml-1"
|
||||
className="ml-1 h-3 w-3"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</Menu.Button>
|
||||
</MenuButton>
|
||||
</div>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
@@ -53,58 +53,58 @@ export default function AppSelector({ appItems, curApp }: IAppSelectorProps) {
|
||||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<Menu.Items
|
||||
<MenuItems
|
||||
className="
|
||||
absolute -left-11 right-0 mt-1.5 w-60 max-w-80
|
||||
divide-y divide-gray-100 origin-top-right rounded-lg bg-white
|
||||
origin-top-right divide-y divide-gray-100 rounded-lg bg-white
|
||||
shadow-lg
|
||||
"
|
||||
>
|
||||
{!!appItems.length && (<div className="px-1 py-1 overflow-auto" style={{ maxHeight: '50vh' }}>
|
||||
{!!appItems.length && (<div className="overflow-auto px-1 py-1" style={{ maxHeight: '50vh' }}>
|
||||
{
|
||||
appItems.map((app: AppDetailResponse) => (
|
||||
<Menu.Item key={app.id}>
|
||||
<MenuItem key={app.id}>
|
||||
<div className={itemClassName} onClick={() =>
|
||||
router.push(`/app/${app.id}/${isCurrentWorkspaceEditor ? 'configuration' : 'overview'}`)
|
||||
}>
|
||||
<div className='relative w-6 h-6 mr-2 bg-[#D5F5F6] rounded-[6px]'>
|
||||
<div className='relative mr-2 h-6 w-6 rounded-[6px] bg-[#D5F5F6]'>
|
||||
<AppIcon size='tiny' />
|
||||
<div className='flex justify-center items-center absolute -right-0.5 -bottom-0.5 w-2.5 h-2.5 bg-white rounded'>
|
||||
<div className='absolute -bottom-0.5 -right-0.5 flex h-2.5 w-2.5 items-center justify-center rounded bg-white'>
|
||||
<Indicator />
|
||||
</div>
|
||||
</div>
|
||||
{app.name}
|
||||
</div>
|
||||
</Menu.Item>
|
||||
</MenuItem>
|
||||
))
|
||||
}
|
||||
</div>)}
|
||||
{isCurrentWorkspaceEditor && <Menu.Item>
|
||||
{isCurrentWorkspaceEditor && <MenuItem>
|
||||
<div className='p-1' onClick={() => setShowNewAppDialog(true)}>
|
||||
<div
|
||||
className='flex items-center h-12 rounded-lg cursor-pointer hover:bg-gray-100'
|
||||
className='flex h-12 cursor-pointer items-center rounded-lg hover:bg-gray-100'
|
||||
>
|
||||
<div
|
||||
className='
|
||||
flex justify-center items-center
|
||||
ml-4 mr-2 w-6 h-6 bg-gray-100 rounded-[6px]
|
||||
border-[0.5px] border-gray-200 border-dashed
|
||||
ml-4 mr-2 flex
|
||||
h-6 w-6 items-center justify-center rounded-[6px] border-[0.5px]
|
||||
border-dashed border-gray-200 bg-gray-100
|
||||
'
|
||||
>
|
||||
<PlusIcon className='w-4 h-4 text-gray-500' />
|
||||
<PlusIcon className='h-4 w-4 text-gray-500' />
|
||||
</div>
|
||||
<div className='font-normal text-[14px] text-gray-700'>{t('common.menus.newApp')}</div>
|
||||
<div className='text-[14px] font-normal text-gray-700'>{t('common.menus.newApp')}</div>
|
||||
</div>
|
||||
</div>
|
||||
</Menu.Item>
|
||||
</MenuItem>
|
||||
}
|
||||
</Menu.Items>
|
||||
</MenuItems>
|
||||
</Transition>
|
||||
</Menu>
|
||||
<CreateAppDialog
|
||||
show={showNewAppDialog}
|
||||
onClose={() => setShowNewAppDialog(false)}
|
||||
onSuccess={() => {}}
|
||||
onSuccess={() => { }}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -42,8 +42,8 @@ const DatasetNav = () => {
|
||||
|
||||
return (
|
||||
<Nav
|
||||
icon={<RiBook2Line className='w-4 h-4' />}
|
||||
activeIcon={<RiBook2Fill className='w-4 h-4' />}
|
||||
icon={<RiBook2Line className='h-4 w-4' />}
|
||||
activeIcon={<RiBook2Fill className='h-4 w-4' />}
|
||||
text={t('common.menus.datasets')}
|
||||
activeSegment='datasets'
|
||||
link='/datasets'
|
||||
|
||||
@@ -20,13 +20,13 @@ const EnvNav = () => {
|
||||
|
||||
return (
|
||||
<div className={`
|
||||
flex items-center h-[22px] mr-4 rounded-md px-2 text-xs font-medium border
|
||||
mr-4 flex h-[22px] items-center rounded-md border px-2 text-xs font-medium
|
||||
${headerEnvClassName[langeniusVersionInfo.current_env]}
|
||||
`}>
|
||||
{
|
||||
langeniusVersionInfo.current_env === 'TESTING' && (
|
||||
<>
|
||||
<Beaker02 className='w-3 h-3 mr-1' />
|
||||
<Beaker02 className='mr-1 h-3 w-3' />
|
||||
{t('common.environment.testing')}
|
||||
</>
|
||||
)
|
||||
@@ -34,7 +34,7 @@ const EnvNav = () => {
|
||||
{
|
||||
langeniusVersionInfo.current_env === 'DEVELOPMENT' && (
|
||||
<>
|
||||
<TerminalSquare className='w-3 h-3 mr-1' />
|
||||
<TerminalSquare className='mr-1 h-3 w-3' />
|
||||
{t('common.environment.development')}
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -27,8 +27,8 @@ const ExploreNav = ({
|
||||
)}>
|
||||
{
|
||||
activated
|
||||
? <RiPlanetFill className='mr-2 w-4 h-4' />
|
||||
: <RiPlanetLine className='mr-2 w-4 h-4' />
|
||||
? <RiPlanetFill className='mr-2 h-4 w-4' />
|
||||
: <RiPlanetLine className='mr-2 h-4 w-4' />
|
||||
}
|
||||
{t('common.menus.explore')}
|
||||
</Link>
|
||||
|
||||
@@ -49,18 +49,18 @@ const Header = () => {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [selectedSegment])
|
||||
return (
|
||||
<div className='flex flex-1 items-center justify-between px-4 bg-background-body'>
|
||||
<div className='flex flex-1 items-center justify-between bg-background-body px-4'>
|
||||
<div className='flex items-center'>
|
||||
{isMobile && <div
|
||||
className='flex items-center justify-center h-8 w-8 cursor-pointer'
|
||||
className='flex h-8 w-8 cursor-pointer items-center justify-center'
|
||||
onClick={toggle}
|
||||
>
|
||||
<Bars3Icon className="h-4 w-4 text-gray-500" />
|
||||
</div>}
|
||||
{
|
||||
!isMobile
|
||||
&& <div className='flex w-64 p-2 pl-3 gap-1.5 items-center shrink-0 self-stretch'>
|
||||
<Link href="/apps" className='flex w-8 h-8 items-center justify-center gap-2 shrink-0'>
|
||||
&& <div className='flex w-64 shrink-0 items-center gap-1.5 self-stretch p-2 pl-3'>
|
||||
<Link href="/apps" className='flex h-8 w-8 shrink-0 items-center justify-center gap-2'>
|
||||
<LogoSite className='object-contain' />
|
||||
</Link>
|
||||
<div className='font-light text-divider-deep'>/</div>
|
||||
@@ -75,7 +75,7 @@ const Header = () => {
|
||||
</div >
|
||||
{isMobile && (
|
||||
<div className='flex'>
|
||||
<Link href="/apps" className='flex items-center mr-4'>
|
||||
<Link href="/apps" className='mr-4 flex items-center'>
|
||||
<LogoSite />
|
||||
</Link>
|
||||
<div className='font-light text-divider-deep'>/</div>
|
||||
@@ -92,7 +92,7 @@ const Header = () => {
|
||||
</div>
|
||||
)
|
||||
}
|
||||
<div className='flex items-center shrink-0'>
|
||||
<div className='flex shrink-0 items-center'>
|
||||
<EnvNav />
|
||||
<div className='mr-3'>
|
||||
<PluginsNav />
|
||||
@@ -101,7 +101,7 @@ const Header = () => {
|
||||
</div>
|
||||
{
|
||||
(isMobile && isShowNavMenu) && (
|
||||
<div className='w-full flex flex-col p-2 gap-y-1'>
|
||||
<div className='flex w-full flex-col gap-y-1 p-2'>
|
||||
{!isCurrentWorkspaceDatasetOperator && <ExploreNav className={navClassName} />}
|
||||
{!isCurrentWorkspaceDatasetOperator && <AppNav />}
|
||||
{(isCurrentWorkspaceEditor || isCurrentWorkspaceDatasetOperator) && <DatasetNav />}
|
||||
|
||||
@@ -16,7 +16,7 @@ const LicenseNav = () => {
|
||||
const expiredAt = systemFeatures.license?.expired_at
|
||||
const count = dayjs(expiredAt).diff(dayjs(), 'days')
|
||||
return <PremiumBadge color='orange' className='select-none'>
|
||||
<RiHourglass2Fill className='flex items-center pl-0.5 size-3 text-components-premium-badge-indigo-text-stop-0' />
|
||||
<RiHourglass2Fill className='flex size-3 items-center pl-0.5 text-components-premium-badge-indigo-text-stop-0' />
|
||||
{count <= 1 && <span className='system-xs-medium px-0.5'>{t('common.license.expiring', { count })}</span>}
|
||||
{count > 1 && <span className='system-xs-medium px-0.5'>{t('common.license.expiring_plural', { count })}</span>}
|
||||
</PremiumBadge>
|
||||
|
||||
@@ -24,14 +24,14 @@ const MaintenanceNotice = () => {
|
||||
return null
|
||||
|
||||
return (
|
||||
<div className='shrink-0 flex items-center px-4 h-[38px] bg-[#FFFAEB] border-b border-[0.5px] border-b-[#FEF0C7] z-20'>
|
||||
<div className='shrink-0 flex items-center mr-2 px-2 h-[22px] bg-[#F79009] text-white text-[11px] font-medium rounded-xl'>{titleByLocale[locale]}</div>
|
||||
<div className='z-20 flex h-[38px] shrink-0 items-center border-[0.5px] border-b border-b-[#FEF0C7] bg-[#FFFAEB] px-4'>
|
||||
<div className='mr-2 flex h-[22px] shrink-0 items-center rounded-xl bg-[#F79009] px-2 text-[11px] font-medium text-white'>{titleByLocale[locale]}</div>
|
||||
{
|
||||
(NOTICE_I18N.href && NOTICE_I18N.href !== '#')
|
||||
? <div className='grow text-xs font-medium text-gray-700 cursor-pointer' onClick={handleJumpNotice}>{descByLocale[locale]}</div>
|
||||
? <div className='grow cursor-pointer text-xs font-medium text-gray-700' onClick={handleJumpNotice}>{descByLocale[locale]}</div>
|
||||
: <div className='grow text-xs font-medium text-gray-700'>{descByLocale[locale]}</div>
|
||||
}
|
||||
<X className='shrink-0 w-4 h-4 text-gray-500 cursor-pointer' onClick={handleCloseNotice} />
|
||||
<X className='h-4 w-4 shrink-0 cursor-pointer text-gray-500' onClick={handleCloseNotice} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -46,8 +46,8 @@ const Nav = ({
|
||||
|
||||
return (
|
||||
<div className={`
|
||||
flex items-center h-8 mr-0 sm:mr-3 px-0.5 rounded-xl text-sm shrink-0 font-medium
|
||||
${isActivated && 'bg-components-main-nav-nav-button-bg-active shadow-md font-semibold'}
|
||||
mr-0 flex h-8 shrink-0 items-center rounded-xl px-0.5 text-sm font-medium sm:mr-3
|
||||
${isActivated && 'bg-components-main-nav-nav-button-bg-active font-semibold shadow-md'}
|
||||
${!curNav && !isActivated && 'hover:bg-components-main-nav-nav-button-bg-hover'}
|
||||
`}>
|
||||
<Link href={link + (linkLastSearchParams && `?${linkLastSearchParams}`)}>
|
||||
@@ -64,7 +64,7 @@ const Nav = ({
|
||||
<div className='mr-2'>
|
||||
{
|
||||
(hovered && curNav)
|
||||
? <ArrowNarrowLeft className='w-4 h-4' />
|
||||
? <ArrowNarrowLeft className='h-4 w-4' />
|
||||
: isActivated
|
||||
? activeIcon
|
||||
: icon
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
RiArrowDownSLine,
|
||||
RiArrowRightSLine,
|
||||
} from '@remixicon/react'
|
||||
import { Menu, Transition } from '@headlessui/react'
|
||||
import { Menu, MenuButton, MenuItems, Transition } from '@headlessui/react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { debounce } from 'lodash-es'
|
||||
import cn from '@/utils/classnames'
|
||||
@@ -57,53 +57,53 @@ const NavSelector = ({ curNav, navs, createText, isApp, onCreate, onLoadmore }:
|
||||
<Menu as="div" className="relative inline-block text-left">
|
||||
{({ open }) => (
|
||||
<>
|
||||
<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-components-main-nav-nav-button-text-active hover:hover:bg-components-main-nav-nav-button-bg-active-hover',
|
||||
<MenuButton className={cn(
|
||||
'hover:hover:bg-components-main-nav-nav-button-bg-active-hover group inline-flex h-7 w-full items-center justify-center rounded-[10px] pl-2 pr-2.5 text-[14px] font-semibold text-components-main-nav-nav-button-text-active',
|
||||
open && 'bg-components-main-nav-nav-button-bg-active',
|
||||
)}>
|
||||
<div className='max-w-[180px] truncate' title={curNav?.name}>{curNav?.name}</div>
|
||||
<RiArrowDownSLine
|
||||
className={cn('shrink-0 w-3 h-3 ml-1 opacity-50 group-hover:opacity-100', open && '!opacity-100')}
|
||||
className={cn('ml-1 h-3 w-3 shrink-0 opacity-50 group-hover:opacity-100', open && '!opacity-100')}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</Menu.Button>
|
||||
<Menu.Items
|
||||
</MenuButton>
|
||||
<MenuItems
|
||||
className="
|
||||
absolute -left-11 right-0 mt-1.5 w-60 max-w-80
|
||||
divide-y divide-gray-100 origin-top-right rounded-lg bg-white
|
||||
origin-top-right divide-y divide-gray-100 rounded-lg bg-white
|
||||
shadow-lg
|
||||
"
|
||||
>
|
||||
<div className="px-1 py-1 overflow-auto" style={{ maxHeight: '50vh' }} onScroll={handleScroll}>
|
||||
<div className="overflow-auto px-1 py-1" style={{ maxHeight: '50vh' }} onScroll={handleScroll}>
|
||||
{
|
||||
navs.map(nav => (
|
||||
<Menu.Item key={nav.id}>
|
||||
<div className='flex items-center w-full px-3 py-[6px] text-gray-700 text-[14px] rounded-lg font-normal hover:bg-gray-100 cursor-pointer truncate' onClick={() => {
|
||||
<MenuItems key={nav.id}>
|
||||
<div className='flex w-full cursor-pointer items-center truncate rounded-lg px-3 py-[6px] text-[14px] font-normal text-gray-700 hover:bg-gray-100' onClick={() => {
|
||||
if (curNav?.id === nav.id)
|
||||
return
|
||||
setAppDetail()
|
||||
router.push(nav.link)
|
||||
}} title={nav.name}>
|
||||
<div className='relative w-6 h-6 mr-2 rounded-md'>
|
||||
<AppIcon size='tiny' iconType={nav.icon_type} icon={nav.icon} background={nav.icon_background} imageUrl={nav.icon_url}/>
|
||||
<div className='relative mr-2 h-6 w-6 rounded-md'>
|
||||
<AppIcon size='tiny' iconType={nav.icon_type} icon={nav.icon} background={nav.icon_background} imageUrl={nav.icon_url} />
|
||||
{!!nav.mode && (
|
||||
<span className={cn(
|
||||
'absolute w-3.5 h-3.5 -bottom-0.5 -right-0.5 p-0.5 bg-white rounded border-[0.5px] border-[rgba(0,0,0,0.02)] shadow-sm',
|
||||
'absolute -bottom-0.5 -right-0.5 h-3.5 w-3.5 rounded border-[0.5px] border-[rgba(0,0,0,0.02)] bg-white p-0.5 shadow-sm',
|
||||
)}>
|
||||
{nav.mode === 'advanced-chat' && (
|
||||
<ChatBot className='w-2.5 h-2.5 text-[#1570EF]' />
|
||||
<ChatBot className='h-2.5 w-2.5 text-[#1570EF]' />
|
||||
)}
|
||||
{nav.mode === 'agent-chat' && (
|
||||
<CuteRobot className='w-2.5 h-2.5 text-indigo-600' />
|
||||
<CuteRobot className='h-2.5 w-2.5 text-indigo-600' />
|
||||
)}
|
||||
{nav.mode === 'chat' && (
|
||||
<ChatBot className='w-2.5 h-2.5 text-[#1570EF]' />
|
||||
<ChatBot className='h-2.5 w-2.5 text-[#1570EF]' />
|
||||
)}
|
||||
{nav.mode === 'completion' && (
|
||||
<AiText className='w-2.5 h-2.5 text-[#0E9384]' />
|
||||
<AiText className='h-2.5 w-2.5 text-[#0E9384]' />
|
||||
)}
|
||||
{nav.mode === 'workflow' && (
|
||||
<Route className='w-2.5 h-2.5 text-[#f79009]' />
|
||||
<Route className='h-2.5 w-2.5 text-[#f79009]' />
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
@@ -112,38 +112,38 @@ const NavSelector = ({ curNav, navs, createText, isApp, onCreate, onLoadmore }:
|
||||
{nav.name}
|
||||
</div>
|
||||
</div>
|
||||
</Menu.Item>
|
||||
</MenuItems>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
{!isApp && isCurrentWorkspaceEditor && (
|
||||
<Menu.Button className='p-1 w-full'>
|
||||
<MenuButton className='w-full p-1'>
|
||||
<div onClick={() => onCreate('')} className={cn(
|
||||
'flex items-center gap-2 px-3 py-[6px] rounded-lg cursor-pointer hover:bg-gray-100',
|
||||
'flex cursor-pointer items-center gap-2 rounded-lg px-3 py-[6px] hover:bg-gray-100',
|
||||
)}>
|
||||
<div className='shrink-0 flex justify-center items-center w-6 h-6 bg-gray-50 rounded-[6px] border-[0.5px] border-gray-200 border'>
|
||||
<RiAddLine className='w-4 h-4 text-gray-500' />
|
||||
<div className='flex h-6 w-6 shrink-0 items-center justify-center rounded-[6px] border border-[0.5px] border-gray-200 bg-gray-50'>
|
||||
<RiAddLine className='h-4 w-4 text-gray-500' />
|
||||
</div>
|
||||
<div className='grow text-left font-normal text-[14px] text-gray-700'>{createText}</div>
|
||||
<div className='grow text-left text-[14px] font-normal text-gray-700'>{createText}</div>
|
||||
</div>
|
||||
</Menu.Button>
|
||||
</MenuButton>
|
||||
)}
|
||||
{isApp && isCurrentWorkspaceEditor && (
|
||||
<Menu as="div" className="relative w-full h-full">
|
||||
<Menu as="div" className="relative h-full w-full">
|
||||
{({ open }) => (
|
||||
<>
|
||||
<Menu.Button className='p-1 w-full'>
|
||||
<MenuButton className='w-full p-1'>
|
||||
<div className={cn(
|
||||
'flex items-center gap-2 px-3 py-[6px] rounded-lg cursor-pointer hover:bg-gray-100',
|
||||
'flex cursor-pointer items-center gap-2 rounded-lg px-3 py-[6px] hover:bg-gray-100',
|
||||
open && '!bg-gray-100',
|
||||
)}>
|
||||
<div className='shrink-0 flex justify-center items-center w-6 h-6 bg-gray-50 rounded-[6px] border-[0.5px] border-gray-200 border'>
|
||||
<RiAddLine className='w-4 h-4 text-gray-500' />
|
||||
<div className='flex h-6 w-6 shrink-0 items-center justify-center rounded-[6px] border border-[0.5px] border-gray-200 bg-gray-50'>
|
||||
<RiAddLine className='h-4 w-4 text-gray-500' />
|
||||
</div>
|
||||
<div className='grow text-left font-normal text-[14px] text-gray-700'>{createText}</div>
|
||||
<RiArrowRightSLine className='shrink-0 w-3.5 h-3.5 text-gray-500' />
|
||||
<div className='grow text-left text-[14px] font-normal text-gray-700'>{createText}</div>
|
||||
<RiArrowRightSLine className='h-3.5 w-3.5 shrink-0 text-gray-500' />
|
||||
</div>
|
||||
</Menu.Button>
|
||||
</MenuButton>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
enter="transition ease-out duration-100"
|
||||
@@ -153,32 +153,32 @@ const NavSelector = ({ curNav, navs, createText, isApp, onCreate, onLoadmore }:
|
||||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<Menu.Items className={cn(
|
||||
'absolute top-[3px] right-[-198px] min-w-[200px] z-10 bg-white border-[0.5px] border-gray-200 rounded-lg shadow-lg',
|
||||
<MenuItems className={cn(
|
||||
'absolute right-[-198px] top-[3px] z-10 min-w-[200px] rounded-lg border-[0.5px] border-gray-200 bg-white shadow-lg',
|
||||
)}>
|
||||
<div className='p-1'>
|
||||
<div className={cn('flex items-center px-3 py-[6px] rounded-lg cursor-pointer hover:bg-gray-100 text-gray-700 font-normal')} onClick={() => onCreate('blank')}>
|
||||
<FilePlus01 className='shrink-0 mr-2 w-4 h-4 text-gray-600' />
|
||||
<div className={cn('flex cursor-pointer items-center rounded-lg px-3 py-[6px] font-normal text-gray-700 hover:bg-gray-100')} onClick={() => onCreate('blank')}>
|
||||
<FilePlus01 className='mr-2 h-4 w-4 shrink-0 text-gray-600' />
|
||||
{t('app.newApp.startFromBlank')}
|
||||
</div>
|
||||
<div className={cn('flex items-center px-3 py-[6px] rounded-lg cursor-pointer hover:bg-gray-100 text-gray-700 font-normal')} onClick={() => onCreate('template')}>
|
||||
<FilePlus02 className='shrink-0 mr-2 w-4 h-4 text-gray-600' />
|
||||
<div className={cn('flex cursor-pointer items-center rounded-lg px-3 py-[6px] font-normal text-gray-700 hover:bg-gray-100')} onClick={() => onCreate('template')}>
|
||||
<FilePlus02 className='mr-2 h-4 w-4 shrink-0 text-gray-600' />
|
||||
{t('app.newApp.startFromTemplate')}
|
||||
</div>
|
||||
</div>
|
||||
<div className='p-1 border-t border-gray-100'>
|
||||
<div className={cn('flex items-center px-3 py-[6px] rounded-lg cursor-pointer hover:bg-gray-100 text-gray-700 font-normal')} onClick={() => onCreate('dsl')}>
|
||||
<FileArrow01 className='shrink-0 mr-2 w-4 h-4 text-gray-600' />
|
||||
<div className='border-t border-gray-100 p-1'>
|
||||
<div className={cn('flex cursor-pointer items-center rounded-lg px-3 py-[6px] font-normal text-gray-700 hover:bg-gray-100')} onClick={() => onCreate('dsl')}>
|
||||
<FileArrow01 className='mr-2 h-4 w-4 shrink-0 text-gray-600' />
|
||||
{t('app.importDSL')}
|
||||
</div>
|
||||
</div>
|
||||
</Menu.Items>
|
||||
</MenuItems>
|
||||
</Transition>
|
||||
</>
|
||||
)}
|
||||
</Menu>
|
||||
)}
|
||||
</Menu.Items>
|
||||
</MenuItems>
|
||||
</>
|
||||
)}
|
||||
</Menu>
|
||||
|
||||
@@ -19,9 +19,9 @@ const PlanBadge: FC<PlanBadgeProps> = ({ plan, allowHover, sandboxAsUpgrade = fa
|
||||
if (!isFetchedPlan) return null
|
||||
if (plan === Plan.sandbox && sandboxAsUpgrade) {
|
||||
return <PremiumBadge className='select-none' color='blue' allowHover={allowHover} onClick={onClick}>
|
||||
<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'>
|
||||
<span className='whitespace-nowrap p-1'>
|
||||
{t('billing.upgradeBtn.encourageShort')}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -41,14 +41,14 @@ const PluginsNav = ({
|
||||
(isFailed || isInstallingWithError) && !activated && (
|
||||
<Indicator
|
||||
color='red'
|
||||
className='absolute top-[-1px] left-[-1px]'
|
||||
className='absolute left-[-1px] top-[-1px]'
|
||||
/>
|
||||
)
|
||||
}
|
||||
<div className='flex mr-0.5 w-5 h-5 justify-center items-center'>
|
||||
<div className='mr-0.5 flex h-5 w-5 items-center justify-center'>
|
||||
{
|
||||
(!(isInstalling || isInstallingWithError) || activated) && (
|
||||
<Group className='w-4 h-4' />
|
||||
<Group className='h-4 w-4' />
|
||||
)
|
||||
}
|
||||
{
|
||||
|
||||
@@ -28,8 +28,8 @@ const ToolsNav = ({
|
||||
)}>
|
||||
{
|
||||
activated
|
||||
? <RiHammerFill className='mr-2 w-4 h-4' />
|
||||
: <RiHammerLine className='mr-2 w-4 h-4' />
|
||||
? <RiHammerFill className='mr-2 h-4 w-4' />
|
||||
: <RiHammerLine className='mr-2 h-4 w-4' />
|
||||
}
|
||||
{t('common.menus.tools')}
|
||||
</Link>
|
||||
|
||||
Reference in New Issue
Block a user