Feat: Support re-segmentation (#114)

Co-authored-by: John Wang <takatost@gmail.com>
Co-authored-by: Jyong <718720800@qq.com>
Co-authored-by: 金伟强 <iamjoel007@gmail.com>
This commit is contained in:
KVOJJJin
2023-06-01 23:19:36 +08:00
committed by GitHub
parent f65a3ad1cc
commit c67f626b66
61 changed files with 1166 additions and 759 deletions

View File

@@ -1,92 +1,90 @@
import type { Provider, ProviderAzureToken } from '@/models/common'
import { ProviderName } from '@/models/common'
import { useTranslation } from 'react-i18next'
import Link from 'next/link'
import { ArrowTopRightOnSquareIcon } from '@heroicons/react/24/outline'
import { useState, useEffect } from 'react'
import { useEffect, useState } from 'react'
import ProviderInput from '../provider-input'
import useValidateToken, { ValidatedStatus, ValidatedStatusState } from '../provider-input/useValidateToken'
import {
ValidatedErrorIcon,
import type { ValidatedStatusState } from '../provider-input/useValidateToken'
import useValidateToken, { ValidatedStatus } from '../provider-input/useValidateToken'
import {
ValidatedErrorIcon,
ValidatedErrorOnAzureOpenaiTip,
ValidatedSuccessIcon,
ValidatingTip,
ValidatedErrorOnAzureOpenaiTip
} from '../provider-input/Validate'
import { ProviderName } from '@/models/common'
import type { Provider, ProviderAzureToken } from '@/models/common'
interface IAzureProviderProps {
type IAzureProviderProps = {
provider: Provider
onValidatedStatus: (status?: ValidatedStatusState) => void
onTokenChange: (token: ProviderAzureToken) => void
}
const AzureProvider = ({
provider,
provider,
onTokenChange,
onValidatedStatus
onValidatedStatus,
}: IAzureProviderProps) => {
const { t } = useTranslation()
const [token, setToken] = useState<ProviderAzureToken>(provider.provider_name === ProviderName.AZURE_OPENAI ? {...provider.token}: {})
const [ validating, validatedStatus, setValidatedStatus, validate ] = useValidateToken(provider.provider_name)
const [token, setToken] = useState<ProviderAzureToken>(provider.provider_name === ProviderName.AZURE_OPENAI ? { ...provider.token } : {})
const [validating, validatedStatus, setValidatedStatus, validate] = useValidateToken(provider.provider_name)
const handleFocus = (type: keyof ProviderAzureToken) => {
if (token[type] === (provider?.token as ProviderAzureToken)[type]) {
token[type] = ''
setToken({...token})
onTokenChange({...token})
setToken({ ...token })
onTokenChange({ ...token })
setValidatedStatus({})
}
}
const handleChange = (type: keyof ProviderAzureToken, v: string, validate: any) => {
token[type] = v
setToken({...token})
onTokenChange({...token})
validate({...token}, {
setToken({ ...token })
onTokenChange({ ...token })
validate({ ...token }, {
beforeValidating: () => {
if (!token.openai_api_base || !token.openai_api_key) {
setValidatedStatus({})
return false
}
return true
}
},
})
}
const getValidatedIcon = () => {
if (validatedStatus.status === ValidatedStatus.Error || validatedStatus.status === ValidatedStatus.Exceed) {
if (validatedStatus.status === ValidatedStatus.Error || validatedStatus.status === ValidatedStatus.Exceed)
return <ValidatedErrorIcon />
}
if (validatedStatus.status === ValidatedStatus.Success) {
if (validatedStatus.status === ValidatedStatus.Success)
return <ValidatedSuccessIcon />
}
}
const getValidatedTip = () => {
if (validating) {
if (validating)
return <ValidatingTip />
}
if (validatedStatus.status === ValidatedStatus.Error) {
if (validatedStatus.status === ValidatedStatus.Error)
return <ValidatedErrorOnAzureOpenaiTip errorMessage={validatedStatus.message ?? ''} />
}
}
useEffect(() => {
if (typeof onValidatedStatus === 'function') {
if (typeof onValidatedStatus === 'function')
onValidatedStatus(validatedStatus)
}
}, [validatedStatus])
return (
<div className='px-4 py-3'>
<ProviderInput
<ProviderInput
className='mb-4'
name={t('common.provider.azure.apiBase')}
placeholder={t('common.provider.azure.apiBasePlaceholder')}
value={token.openai_api_base}
onChange={(v) => handleChange('openai_api_base', v, validate)}
onChange={v => handleChange('openai_api_base', v, validate)}
onFocus={() => handleFocus('openai_api_base')}
validatedIcon={getValidatedIcon()}
/>
<ProviderInput
<ProviderInput
className='mb-4'
name={t('common.provider.azure.apiKey')}
placeholder={t('common.provider.azure.apiKeyPlaceholder')}
value={token.openai_api_key}
onChange={(v) => handleChange('openai_api_key', v, validate)}
onChange={v => handleChange('openai_api_key', v, validate)}
onFocus={() => handleFocus('openai_api_key')}
validatedIcon={getValidatedIcon()}
validatedTip={getValidatedTip()}

View File

@@ -1,15 +1,15 @@
import { useState } from 'react'
import useSWR from 'swr'
import { fetchProviders } from '@/service/common'
import ProviderItem from './provider-item'
import OpenaiHostedProvider from './openai-hosted-provider'
import type { ProviderHosted } from '@/models/common'
import { LockClosedIcon } from '@heroicons/react/24/solid'
import { useTranslation } from 'react-i18next'
import Link from 'next/link'
import ProviderItem from './provider-item'
import OpenaiHostedProvider from './openai-hosted-provider'
import type { ProviderHosted } from '@/models/common'
import { fetchProviders } from '@/service/common'
import { IS_CE_EDITION } from '@/config'
const providersMap: {[k: string]: any} = {
const providersMap: { [k: string]: any } = {
'openai-custom': {
icon: 'openai',
name: 'OpenAI',
@@ -17,7 +17,7 @@ const providersMap: {[k: string]: any} = {
'azure_openai-custom': {
icon: 'azure',
name: 'Azure OpenAI Service',
}
},
}
// const providersList = [
@@ -56,7 +56,7 @@ const ProviderPage = () => {
const { t } = useTranslation()
const [activeProviderId, setActiveProviderId] = useState('')
const { data, mutate } = useSWR({ url: '/workspaces/current/providers' }, fetchProviders)
const providers = data?.filter(provider => providersMap[`${provider.provider_name}-${provider.provider_type}`])?.map(provider => {
const providers = data?.filter(provider => providersMap[`${provider.provider_name}-${provider.provider_type}`])?.map((provider) => {
const providerKey = `${provider.provider_name}-${provider.provider_type}`
return {
provider,

View File

@@ -1,19 +1,19 @@
import type { Provider } from '@/models/common'
import { useState, useEffect } from 'react'
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import ProviderInput from '../provider-input'
import Link from 'next/link'
import { ArrowTopRightOnSquareIcon } from '@heroicons/react/24/outline'
import useValidateToken, { ValidatedStatus, ValidatedStatusState } from '../provider-input/useValidateToken'
import {
ValidatedErrorIcon,
import ProviderInput from '../provider-input'
import type { ValidatedStatusState } from '../provider-input/useValidateToken'
import useValidateToken, { ValidatedStatus } from '../provider-input/useValidateToken'
import {
ValidatedErrorIcon,
ValidatedErrorOnOpenaiTip,
ValidatedSuccessIcon,
ValidatingTip,
ValidatedExceedOnOpenaiTip,
ValidatedErrorOnOpenaiTip
} from '../provider-input/Validate'
import type { Provider } from '@/models/common'
interface IOpenaiProviderProps {
type IOpenaiProviderProps = {
provider: Provider
onValidatedStatus: (status?: ValidatedStatusState) => void
onTokenChange: (token: string) => void
@@ -22,11 +22,11 @@ interface IOpenaiProviderProps {
const OpenaiProvider = ({
provider,
onValidatedStatus,
onTokenChange
onTokenChange,
}: IOpenaiProviderProps) => {
const { t } = useTranslation()
const [token, setToken] = useState(provider.token as string || '')
const [ validating, validatedStatus, setValidatedStatus, validate ] = useValidateToken(provider.provider_name)
const [validating, validatedStatus, setValidatedStatus, validate] = useValidateToken(provider.provider_name)
const handleFocus = () => {
if (token === provider.token) {
setToken('')
@@ -44,35 +44,32 @@ const OpenaiProvider = ({
return false
}
return true
}
},
})
}
useEffect(() => {
if (typeof onValidatedStatus === 'function') {
if (typeof onValidatedStatus === 'function')
onValidatedStatus(validatedStatus)
}
}, [validatedStatus])
const getValidatedIcon = () => {
if (validatedStatus?.status === ValidatedStatus.Error || validatedStatus.status === ValidatedStatus.Exceed) {
if (validatedStatus?.status === ValidatedStatus.Error || validatedStatus.status === ValidatedStatus.Exceed)
return <ValidatedErrorIcon />
}
if (validatedStatus.status === ValidatedStatus.Success) {
if (validatedStatus.status === ValidatedStatus.Success)
return <ValidatedSuccessIcon />
}
}
const getValidatedTip = () => {
if (validating) {
if (validating)
return <ValidatingTip />
}
if (validatedStatus?.status === ValidatedStatus.Error) {
if (validatedStatus?.status === ValidatedStatus.Error)
return <ValidatedErrorOnOpenaiTip errorMessage={validatedStatus.message ?? ''} />
}
}
return (
<div className='px-4 pt-3 pb-4'>
<ProviderInput
<ProviderInput
value={token}
name={t('common.provider.apiKey')}
placeholder={t('common.provider.enterYourKey')}
@@ -89,4 +86,4 @@ const OpenaiProvider = ({
)
}
export default OpenaiProvider
export default OpenaiProvider

View File

@@ -15,7 +15,7 @@ export const ValidatedSuccessIcon = () => {
export const ValidatingTip = () => {
const { t } = useTranslation()
return (
<div className={`mt-2 text-primary-600 text-xs font-normal`}>
<div className={'mt-2 text-primary-600 text-xs font-normal'}>
{t('common.provider.validating')}
</div>
)
@@ -26,11 +26,11 @@ export const ValidatedExceedOnOpenaiTip = () => {
const { locale } = useContext(I18n)
return (
<div className={`mt-2 text-[#D92D20] text-xs font-normal`}>
<div className={'mt-2 text-[#D92D20] text-xs font-normal'}>
{t('common.provider.apiKeyExceedBill')}&nbsp;
<Link
<Link
className='underline'
href="https://platform.openai.com/account/api-keys"
href="https://platform.openai.com/account/api-keys"
target={'_blank'}>
{locale === 'en' ? 'this link' : '这篇文档'}
</Link>
@@ -42,7 +42,7 @@ export const ValidatedErrorOnOpenaiTip = ({ errorMessage }: { errorMessage: stri
const { t } = useTranslation()
return (
<div className={`mt-2 text-[#D92D20] text-xs font-normal`}>
<div className={'mt-2 text-[#D92D20] text-xs font-normal'}>
{t('common.provider.validatedError')}{errorMessage}
</div>
)
@@ -52,8 +52,8 @@ export const ValidatedErrorOnAzureOpenaiTip = ({ errorMessage }: { errorMessage:
const { t } = useTranslation()
return (
<div className={`mt-2 text-[#D92D20] text-xs font-normal`}>
<div className={'mt-2 text-[#D92D20] text-xs font-normal'}>
{t('common.provider.validatedError')}{errorMessage}
</div>
)
}
}

View File

@@ -1,7 +1,7 @@
import { ChangeEvent } from 'react'
import { ReactElement } from 'react-markdown/lib/react-markdown'
import type { ChangeEvent } from 'react'
import type { ReactElement } from 'react-markdown/lib/react-markdown'
interface IProviderInputProps {
type IProviderInputProps = {
value?: string
name: string
placeholder: string
@@ -20,9 +20,8 @@ const ProviderInput = ({
onChange,
onFocus,
validatedIcon,
validatedTip
validatedTip,
}: IProviderInputProps) => {
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
const inputValue = e.target.value
onChange(inputValue)
@@ -35,12 +34,12 @@ const ProviderInput = ({
flex items-center px-3 bg-white rounded-lg
shadow-[0_1px_2px_rgba(16,24,40,0.05)]
'>
<input
<input
className='
w-full py-[9px]
text-xs font-medium text-gray-700 leading-[18px]
appearance-none outline-none bg-transparent
'
appearance-none outline-none bg-transparent
'
value={value}
placeholder={placeholder}
onChange={handleChange}
@@ -53,4 +52,4 @@ const ProviderInput = ({
)
}
export default ProviderInput
export default ProviderInput

View File

@@ -1,25 +1,26 @@
import { useState, useCallback, SetStateAction, Dispatch } from 'react'
import type { Dispatch, SetStateAction } from 'react'
import { useCallback, useState } from 'react'
import debounce from 'lodash-es/debounce'
import { DebouncedFunc } from 'lodash-es'
import type { DebouncedFunc } from 'lodash-es'
import { validateProviderKey } from '@/service/common'
export enum ValidatedStatus {
Success = 'success',
Error = 'error',
Exceed = 'exceed'
Exceed = 'exceed',
}
export type ValidatedStatusState = {
status?: ValidatedStatus,
status?: ValidatedStatus
message?: string
}
// export type ValidatedStatusState = ValidatedStatus | undefined | ValidatedError
export type SetValidatedStatus = Dispatch<SetStateAction<ValidatedStatusState>>
export type ValidateFn = DebouncedFunc<(token: any, config: ValidateFnConfig) => void>
type ValidateTokenReturn = [
boolean,
ValidatedStatusState,
boolean,
ValidatedStatusState,
SetValidatedStatus,
ValidateFn
ValidateFn,
]
export type ValidateFnConfig = {
beforeValidating: (token: any) => boolean
@@ -29,19 +30,21 @@ const useValidateToken = (providerName: string): ValidateTokenReturn => {
const [validating, setValidating] = useState(false)
const [validatedStatus, setValidatedStatus] = useState<ValidatedStatusState>({})
const validate = useCallback(debounce(async (token: string, config: ValidateFnConfig) => {
if (!config.beforeValidating(token)) {
if (!config.beforeValidating(token))
return false
}
setValidating(true)
try {
const res = await validateProviderKey({ url: `/workspaces/current/providers/${providerName}/token-validate`, body: { token } })
setValidatedStatus(
res.result === 'success'
? { status: ValidatedStatus.Success }
res.result === 'success'
? { status: ValidatedStatus.Success }
: { status: ValidatedStatus.Error, message: res.error })
} catch (e: any) {
}
catch (e: any) {
setValidatedStatus({ status: ValidatedStatus.Error, message: e.message })
} finally {
}
finally {
setValidating(false)
}
}, 500), [])
@@ -50,8 +53,8 @@ const useValidateToken = (providerName: string): ValidateTokenReturn => {
validating,
validatedStatus,
setValidatedStatus,
validate
validate,
]
}
export default useValidateToken
export default useValidateToken

View File

@@ -1,18 +1,19 @@
import { useState } from 'react'
import cn from 'classnames'
import s from './index.module.css'
import { useContext } from 'use-context-selector'
import Indicator from '../../../indicator'
import { useTranslation } from 'react-i18next'
import type { Provider, ProviderAzureToken } from '@/models/common'
import { ProviderName } from '@/models/common'
import Indicator from '../../../indicator'
import OpenaiProvider from '../openai-provider'
import AzureProvider from '../azure-provider'
import { ValidatedStatus, ValidatedStatusState } from '../provider-input/useValidateToken'
import type { ValidatedStatusState } from '../provider-input/useValidateToken'
import { ValidatedStatus } from '../provider-input/useValidateToken'
import s from './index.module.css'
import type { Provider, ProviderAzureToken } from '@/models/common'
import { ProviderName } from '@/models/common'
import { updateProviderAIKey } from '@/service/common'
import { ToastContext } from '@/app/components/base/toast'
interface IProviderItemProps {
type IProviderItemProps = {
icon: string
name: string
provider: Provider
@@ -26,17 +27,17 @@ const ProviderItem = ({
name,
provider,
onActive,
onSave
onSave,
}: IProviderItemProps) => {
const { t } = useTranslation()
const [validatedStatus, setValidatedStatus] = useState<ValidatedStatusState>()
const [loading, setLoading] = useState(false)
const { notify } = useContext(ToastContext)
const [token, setToken] = useState<ProviderAzureToken | string>(
provider.provider_name === 'azure_openai'
provider.provider_name === 'azure_openai'
? { openai_api_base: '', openai_api_key: '' }
: ''
)
: '',
)
const id = `${provider.provider_name}-${provider.provider_type}`
const isOpen = id === activeId
const comingSoon = false
@@ -44,26 +45,30 @@ const ProviderItem = ({
const providerTokenHasSetted = () => {
if (provider.provider_name === ProviderName.AZURE_OPENAI) {
return provider.token && provider.token.openai_api_base && provider.token.openai_api_key ? {
openai_api_base: provider.token.openai_api_base,
openai_api_key: provider.token.openai_api_key
}: undefined
return (provider.token && provider.token.openai_api_base && provider.token.openai_api_key)
? {
openai_api_base: provider.token.openai_api_base,
openai_api_key: provider.token.openai_api_key,
}
: undefined
}
if (provider.provider_name === ProviderName.OPENAI) {
if (provider.provider_name === ProviderName.OPENAI)
return provider.token
}
}
const handleUpdateToken = async () => {
if (loading) return
if (loading)
return
if (validatedStatus?.status === ValidatedStatus.Success) {
try {
setLoading(true)
await updateProviderAIKey({ url: `/workspaces/current/providers/${provider.provider_name}/token`, body: { token } })
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
onActive('')
} catch (e) {
}
catch (e) {
notify({ type: 'error', message: t('common.provider.saveFailed') })
} finally {
}
finally {
setLoading(false)
onSave()
}
@@ -126,18 +131,18 @@ const ProviderItem = ({
</div>
{
provider.provider_name === ProviderName.OPENAI && isOpen && (
<OpenaiProvider
provider={provider}
onValidatedStatus={v => setValidatedStatus(v)}
<OpenaiProvider
provider={provider}
onValidatedStatus={v => setValidatedStatus(v)}
onTokenChange={v => setToken(v)}
/>
)
}
{
provider.provider_name === ProviderName.AZURE_OPENAI && isOpen && (
<AzureProvider
provider={provider}
onValidatedStatus={v => setValidatedStatus(v)}
<AzureProvider
provider={provider}
onValidatedStatus={v => setValidatedStatus(v)}
onTokenChange={v => setToken(v)}
/>
)

View File

@@ -1,7 +1,7 @@
import type { FC } from 'react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useSelectedLayoutSegment, useRouter } from 'next/navigation'
import { useRouter, useSelectedLayoutSegment } from 'next/navigation'
import classNames from 'classnames'
import { CircleStackIcon, PuzzlePieceIcon } from '@heroicons/react/24/outline'
import { CommandLineIcon, Squares2X2Icon } from '@heroicons/react/24/solid'
@@ -15,9 +15,9 @@ import NewAppDialog from '@/app/(commonLayout)/apps/NewAppDialog'
import { WorkspaceProvider } from '@/context/workspace-context'
import { useDatasetsContext } from '@/context/datasets-context'
const BuildAppsIcon = ({isSelected}: {isSelected: boolean}) => (
const BuildAppsIcon = ({ isSelected }: { isSelected: boolean }) => (
<svg className='mr-1' width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.6666 4.85221L7.99998 8.00036M7.99998 8.00036L2.33331 4.85221M7.99998 8.00036L8 14.3337M14 10.7061V5.29468C14 5.06625 14 4.95204 13.9663 4.85017C13.9366 4.76005 13.8879 4.67733 13.8236 4.60754C13.7509 4.52865 13.651 4.47318 13.4514 4.36224L8.51802 1.6215C8.32895 1.51646 8.23442 1.46395 8.1343 1.44336C8.0457 1.42513 7.95431 1.42513 7.8657 1.44336C7.76559 1.46395 7.67105 1.51646 7.48198 1.6215L2.54865 4.36225C2.34896 4.47318 2.24912 4.52865 2.17642 4.60754C2.11211 4.67733 2.06343 4.76005 2.03366 4.85017C2 4.95204 2 5.06625 2 5.29468V10.7061C2 10.9345 2 11.0487 2.03366 11.1506C2.06343 11.2407 2.11211 11.3234 2.17642 11.3932C2.24912 11.4721 2.34897 11.5276 2.54865 11.6385L7.48198 14.3793C7.67105 14.4843 7.76559 14.5368 7.8657 14.5574C7.95431 14.5756 8.0457 14.5756 8.1343 14.5574C8.23442 14.5368 8.32895 14.4843 8.51802 14.3793L13.4514 11.6385C13.651 11.5276 13.7509 11.4721 13.8236 11.3932C13.8879 11.3234 13.9366 11.2407 13.9663 11.1506C14 11.0487 14 10.9345 14 10.7061Z" stroke={isSelected ? '#155EEF': '#667085'} strokeWidth="1.25" strokeLinecap="round" strokeLinejoin="round"/>
<path d="M13.6666 4.85221L7.99998 8.00036M7.99998 8.00036L2.33331 4.85221M7.99998 8.00036L8 14.3337M14 10.7061V5.29468C14 5.06625 14 4.95204 13.9663 4.85017C13.9366 4.76005 13.8879 4.67733 13.8236 4.60754C13.7509 4.52865 13.651 4.47318 13.4514 4.36224L8.51802 1.6215C8.32895 1.51646 8.23442 1.46395 8.1343 1.44336C8.0457 1.42513 7.95431 1.42513 7.8657 1.44336C7.76559 1.46395 7.67105 1.51646 7.48198 1.6215L2.54865 4.36225C2.34896 4.47318 2.24912 4.52865 2.17642 4.60754C2.11211 4.67733 2.06343 4.76005 2.03366 4.85017C2 4.95204 2 5.06625 2 5.29468V10.7061C2 10.9345 2 11.0487 2.03366 11.1506C2.06343 11.2407 2.11211 11.3234 2.17642 11.3932C2.24912 11.4721 2.34897 11.5276 2.54865 11.6385L7.48198 14.3793C7.67105 14.4843 7.76559 14.5368 7.8657 14.5574C7.95431 14.5756 8.0457 14.5756 8.1343 14.5574C8.23442 14.5368 8.32895 14.4843 8.51802 14.3793L13.4514 11.6385C13.651 11.5276 13.7509 11.4721 13.8236 11.3932C13.8879 11.3234 13.9366 11.2407 13.9663 11.1506C14 11.0487 14 10.9345 14 10.7061Z" stroke={isSelected ? '#155EEF' : '#667085'} strokeWidth="1.25" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
)
@@ -51,22 +51,22 @@ const Header: FC<IHeaderProps> = ({ appItems, curApp, userProfile, onLogout, lan
<div className={classNames(
'sticky top-0 left-0 right-0 z-20 flex bg-gray-100 grow-0 shrink-0 basis-auto h-14',
s.header,
isBordered ? 'border-b border-gray-200' : ''
isBordered ? 'border-b border-gray-200' : '',
)}>
<div className={classNames(
s[`header-${langeniusVersionInfo.current_env}`],
'flex flex-1 items-center justify-between px-4'
'flex flex-1 items-center justify-between px-4',
)}>
<div className='flex items-center'>
<Link href="/apps" className='flex items-center mr-3'>
<div className={s['logo']} />
<div className={s.logo} />
</Link>
{/* Add it when has many stars */}
<div className='
flex items-center h-[26px] px-2 bg-white
border border-solid border-[#E5E7EB] rounded-l-[6px] rounded-r-[6px]
'>
<div className={s['alpha']} />
<div className={s.alpha} />
<div className='ml-1 text-xs font-semibold text-gray-700'>{t('common.menus.status')}</div>
</div>
</div>
@@ -74,7 +74,7 @@ const Header: FC<IHeaderProps> = ({ appItems, curApp, userProfile, onLogout, lan
<Link href="/explore/apps" className={classNames(
navClassName, 'group',
isExplore && 'bg-white shadow-[0_2px_5px_-1px_rgba(0,0,0,0.05),0_2px_4px_-2px_rgba(0,0,0,0.05)]',
isExplore ? 'text-primary-600' : 'text-gray-500 hover:bg-gray-200 hover:text-gray-700'
isExplore ? 'text-primary-600' : 'text-gray-500 hover:bg-gray-200 hover:text-gray-700',
)}>
<Squares2X2Icon className='mr-1 w-[18px] h-[18px]' />
{t('common.menus.explore')}
@@ -84,13 +84,13 @@ const Header: FC<IHeaderProps> = ({ appItems, curApp, userProfile, onLogout, lan
text={t('common.menus.apps')}
activeSegment={['apps', 'app']}
link='/apps'
curNav={curApp && { id: curApp.id, name: curApp.name ,icon: curApp.icon, icon_background: curApp.icon_background}}
curNav={curApp && { id: curApp.id, name: curApp.name, icon: curApp.icon, icon_background: curApp.icon_background }}
navs={appItems.map(item => ({
id: item.id,
name: item.name,
link: `/app/${item.id}/overview`,
icon: item.icon,
icon_background: item.icon_background
icon_background: item.icon_background,
}))}
createText={t('common.menus.newApp')}
onCreate={() => setShowNewAppDialog(true)}
@@ -98,7 +98,7 @@ const Header: FC<IHeaderProps> = ({ appItems, curApp, userProfile, onLogout, lan
<Link href="/plugins-coming-soon" className={classNames(
navClassName, 'group',
isPluginsComingSoon && 'bg-white shadow-[0_2px_5px_-1px_rgba(0,0,0,0.05),0_2px_4px_-2px_rgba(0,0,0,0.05)]',
isPluginsComingSoon ? 'text-primary-600' : 'text-gray-500 hover:bg-gray-200 hover:text-gray-700'
isPluginsComingSoon ? 'text-primary-600' : 'text-gray-500 hover:bg-gray-200 hover:text-gray-700',
)}>
<PuzzlePieceIcon className='mr-1 w-[18px] h-[18px]' />
{t('common.menus.plugins')}
@@ -114,7 +114,7 @@ const Header: FC<IHeaderProps> = ({ appItems, curApp, userProfile, onLogout, lan
name: dataset.name,
link: `/datasets/${dataset.id}/documents`,
icon: dataset.icon,
icon_background: dataset.icon_background
icon_background: dataset.icon_background,
}))}
createText={t('common.menus.newDataset')}
onCreate={() => router.push('/datasets/create')}