mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-14 04:45:55 +08:00
Feat: configure dark mode legacy (#15394)
This commit is contained in:
parent
2cf0cb471f
commit
9e220d5d30
@ -11,7 +11,7 @@ const GroupName: FC<IGroupNameProps> = ({
|
||||
}) => {
|
||||
return (
|
||||
<div className='flex items-center mb-1'>
|
||||
<div className='mr-3 leading-[18px] text-xs font-semibold text-gray-500 uppercase'>{name}</div>
|
||||
<div className='mr-3 leading-[18px] text-xs font-semibold text-text-tertiary uppercase'>{name}</div>
|
||||
<div className='grow h-[1px]'
|
||||
style={{
|
||||
background: 'linear-gradient(270deg, rgba(243, 244, 246, 0) 0%, #F3F4F6 100%)',
|
||||
|
@ -20,6 +20,7 @@ import {
|
||||
Clipboard,
|
||||
ClipboardCheck,
|
||||
} from '@/app/components/base/icons/src/vender/line/files'
|
||||
import Button from '@/app/components/base/button'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
import PromptEditor from '@/app/components/base/prompt-editor'
|
||||
import ConfigContext from '@/context/debug-configuration'
|
||||
@ -150,19 +151,20 @@ const AdvancedPromptInput: FC<Props> = ({
|
||||
<RiErrorWarningFill className='mr-1 w-4 h-4 text-[#F79009]' />
|
||||
<div className='leading-[18px] text-[13px] font-medium text-[#DC6803]'>{t('appDebug.promptMode.contextMissing')}</div>
|
||||
</div>
|
||||
<div
|
||||
className='flex items-center h-6 px-2 rounded-md bg-[#fff] border border-gray-200 shadow-xs text-xs font-medium text-primary-600 cursor-pointer'
|
||||
<Button
|
||||
size='small'
|
||||
variant='secondary-accent'
|
||||
onClick={onHideContextMissingTip}
|
||||
>{t('common.operation.ok')}</div>
|
||||
>{t('common.operation.ok')}</Button>
|
||||
</div>
|
||||
)
|
||||
return (
|
||||
<div className={`relative ${!isContextMissing ? s.gradientBorder : s.warningBorder}`}>
|
||||
<div className='rounded-xl bg-white'>
|
||||
<div className={`bg-gradient-to-r from-components-input-border-active-prompt-1 to-components-input-border-active-prompt-2 rounded-xl p-0.5 shadow-xs ${!isContextMissing ? '' : s.warningBorder}`}>
|
||||
<div className='rounded-xl bg-background-default'>
|
||||
{isContextMissing
|
||||
? contextMissing
|
||||
: (
|
||||
<div className={cn(s.boxHeader, 'flex justify-between items-center h-11 pt-2 pr-3 pb-1 pl-4 rounded-tl-xl rounded-tr-xl bg-white hover:shadow-xs')}>
|
||||
<div className={cn(s.boxHeader, 'flex justify-between items-center h-11 pt-2 pr-3 pb-1 pl-4 rounded-tl-xl rounded-tr-xl bg-background-default hover:shadow-xs')}>
|
||||
{isChatMode
|
||||
? (
|
||||
<MessageTypeSelector value={type} onChange={onTypeChange} />
|
||||
@ -182,30 +184,30 @@ const AdvancedPromptInput: FC<Props> = ({
|
||||
</div>)}
|
||||
<div className={cn(s.optionWrap, 'items-center space-x-1')}>
|
||||
{canDelete && (
|
||||
<RiDeleteBinLine onClick={onDelete} className='h-6 w-6 p-1 text-gray-500 cursor-pointer' />
|
||||
<RiDeleteBinLine onClick={onDelete} className='h-6 w-6 p-1 text-text-tertiary cursor-pointer' />
|
||||
)}
|
||||
{!isCopied
|
||||
? (
|
||||
<Clipboard className='h-6 w-6 p-1 text-gray-500 cursor-pointer' onClick={() => {
|
||||
<Clipboard className='h-6 w-6 p-1 text-text-tertiary cursor-pointer' onClick={() => {
|
||||
copy(value)
|
||||
setIsCopied(true)
|
||||
}} />
|
||||
)
|
||||
: (
|
||||
<ClipboardCheck className='h-6 w-6 p-1 text-gray-500' />
|
||||
<ClipboardCheck className='h-6 w-6 p-1 text-text-tertiary' />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<PromptEditorHeightResizeWrap
|
||||
className='px-4 min-h-[102px] overflow-y-auto text-sm text-gray-700'
|
||||
className='px-4 min-h-[102px] overflow-y-auto text-sm text-text-secondary'
|
||||
height={editorHeight}
|
||||
minHeight={minHeight}
|
||||
onHeightChange={setEditorHeight}
|
||||
footer={(
|
||||
<div className='pl-4 pb-2 flex'>
|
||||
<div className="h-[18px] leading-[18px] px-1 rounded-md bg-gray-100 text-xs text-gray-500">{value.length}</div>
|
||||
<div className="h-[18px] leading-[18px] px-1 rounded-md bg-divider-regular text-xs text-text-tertiary">{value.length}</div>
|
||||
</div>
|
||||
)}
|
||||
hideResize={noResize}
|
||||
|
@ -39,21 +39,17 @@ const ConfirmAddVar: FC<IConfirmAddVarProps> = ({
|
||||
}}>
|
||||
<div
|
||||
ref={mainContentRef}
|
||||
className='w-[420px] rounded-xl bg-gray-50 p-6'
|
||||
className='w-[420px] rounded-xl bg-components-panel-bg p-6'
|
||||
style={{
|
||||
boxShadow: '0px 12px 16px -4px rgba(16, 24, 40, 0.08), 0px 4px 6px -2px rgba(16, 24, 40, 0.03)',
|
||||
}}
|
||||
>
|
||||
<div className='flex items-start space-x-3'>
|
||||
<div
|
||||
className='shrink-0 flex items-center justify-center h-10 w-10 rounded-xl border border-gray-100'
|
||||
style={{
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.9)',
|
||||
boxShadow: '0px 12px 16px -4px rgba(16, 24, 40, 0.08), 0px 4px 6px -2px rgba(16, 24, 40, 0.03)',
|
||||
}}
|
||||
className='shrink-0 flex items-center justify-center h-10 w-10 bg-components-card-bg-alt rounded-xl border border-components-card-border shadow-lg'
|
||||
>{VarIcon}</div>
|
||||
<div className='grow-1'>
|
||||
<div className='text-sm font-medium text-gray-900'>{t('appDebug.autoAddVar')}</div>
|
||||
<div className='text-sm font-medium text-text-primary'>{t('appDebug.autoAddVar')}</div>
|
||||
<div className='flex flex-wrap mt-[15px] max-h-[66px] overflow-y-auto px-1 space-x-1'>
|
||||
{varNameArr.map(name => (
|
||||
<VarHighlight key={name} name={name} />
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
} from '@remixicon/react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import SimplePromptInput from './simple-prompt-input'
|
||||
import Button from '@/app/components/base/button'
|
||||
import AdvancedMessageInput from '@/app/components/app/configuration/config-prompt/advanced-prompt-input'
|
||||
import { PromptRole } from '@/models/debug'
|
||||
import type { PromptItem, PromptVariable } from '@/models/debug'
|
||||
@ -155,12 +156,12 @@ const Prompt: FC<IPromptProps> = ({
|
||||
}
|
||||
</div>
|
||||
{(modelModeType === ModelModeType.chat && (currentAdvancedPrompt as PromptItem[]).length < MAX_PROMPT_MESSAGE_LENGTH) && (
|
||||
<div
|
||||
<Button
|
||||
onClick={handleAddMessage}
|
||||
className='mt-3 flex items-center h-8 justify-center bg-gray-50 rounded-lg cursor-pointer text-[13px] font-medium text-gray-700 space-x-2'>
|
||||
<RiAddLine className='w-4 h-4' />
|
||||
className='mt-3 w-full'>
|
||||
<RiAddLine className='w-4 h-4 mr-2' />
|
||||
<div>{t('appDebug.promptMode.operation.addMessage')}</div>
|
||||
</div>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
@ -29,7 +29,7 @@ const MessageTypeSelector: FC<Props> = ({
|
||||
<ChevronSelectorVertical className='w-3 h-3 ' />
|
||||
</div>
|
||||
{showOption && (
|
||||
<div className='absolute z-10 top-[30px] p-1 border border-gray-200 shadow-lg rounded-lg bg-white'>
|
||||
<div className='absolute z-10 top-[30px] p-1 border border-components-panel-border shadow-lg rounded-lg bg-components-panel-bg'>
|
||||
{allTypes.map(type => (
|
||||
<div
|
||||
key={type}
|
||||
@ -37,7 +37,7 @@ const MessageTypeSelector: FC<Props> = ({
|
||||
setHide()
|
||||
onChange(type)
|
||||
}}
|
||||
className='flex items-center h-9 min-w-[44px] px-3 rounded-lg cursor-pointer text-sm font-medium text-gray-700 uppercase hover:bg-gray-50'
|
||||
className='flex items-center h-9 min-w-[44px] px-3 rounded-lg cursor-pointer text-sm font-medium text-text-secondary uppercase hover:bg-state-base-hover'
|
||||
>{type}</div>
|
||||
))
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import { useBoolean } from 'ahooks'
|
||||
import produce from 'immer'
|
||||
import { useContext } from 'use-context-selector'
|
||||
import ConfirmAddVar from './confirm-add-var'
|
||||
import s from './style.module.css'
|
||||
import PromptEditorHeightResizeWrap from './prompt-editor-height-resize-wrap'
|
||||
import cn from '@/utils/classnames'
|
||||
import type { PromptVariable } from '@/models/debug'
|
||||
@ -48,7 +47,6 @@ const Prompt: FC<ISimplePromptInput> = ({
|
||||
readonly = false,
|
||||
onChange,
|
||||
noTitle,
|
||||
gradientBorder,
|
||||
editorHeight: initEditorHeight,
|
||||
noResize,
|
||||
}) => {
|
||||
@ -161,12 +159,12 @@ const Prompt: FC<ISimplePromptInput> = ({
|
||||
const [editorHeight, setEditorHeight] = useState(minHeight)
|
||||
|
||||
return (
|
||||
<div className={cn((!readonly || gradientBorder) ? `${s.gradientBorder}` : 'bg-gray-50', ' relative shadow-md')}>
|
||||
<div className='rounded-xl bg-[#EEF4FF]'>
|
||||
<div className={cn('relative bg-gradient-to-r from-components-input-border-active-prompt-1 to-components-input-border-active-prompt-2 rounded-xl p-0.5 shadow-xs')}>
|
||||
<div className='rounded-xl bg-background-section-burn'>
|
||||
{!noTitle && (
|
||||
<div className="flex justify-between items-center h-11 pl-3 pr-6">
|
||||
<div className="flex justify-between items-center h-11 pl-3 pr-2.5">
|
||||
<div className="flex items-center space-x-1">
|
||||
<div className='h2'>{mode !== AppType.completion ? t('appDebug.chatSubTitle') : t('appDebug.completionSubTitle')}</div>
|
||||
<div className='h2 system-sm-semibold-uppercase text-text-secondary'>{mode !== AppType.completion ? t('appDebug.chatSubTitle') : t('appDebug.completionSubTitle')}</div>
|
||||
{!readonly && (
|
||||
<Tooltip
|
||||
popupContent={
|
||||
@ -186,14 +184,14 @@ const Prompt: FC<ISimplePromptInput> = ({
|
||||
)}
|
||||
|
||||
<PromptEditorHeightResizeWrap
|
||||
className='px-4 pt-2 min-h-[228px] bg-white rounded-t-xl text-sm text-gray-700'
|
||||
className='px-4 pt-2 min-h-[228px] bg-background-default rounded-t-xl text-sm text-text-secondary'
|
||||
height={editorHeight}
|
||||
minHeight={minHeight}
|
||||
onHeightChange={setEditorHeight}
|
||||
hideResize={noResize}
|
||||
footer={(
|
||||
<div className='pl-4 pb-2 flex bg-white rounded-b-xl'>
|
||||
<div className="h-[18px] leading-[18px] px-1 rounded-md bg-gray-100 text-xs text-gray-500">{promptTemplate.length}</div>
|
||||
<div className='pl-4 pb-2 flex bg-background-default rounded-b-xl'>
|
||||
<div className="h-[18px] leading-[18px] px-1 rounded-md bg-components-badge-bg-gray-soft text-xs text-text-tertiary">{promptTemplate.length}</div>
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
|
@ -2,7 +2,10 @@
|
||||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Generator } from '@/app/components/base/icons/src/vender/other'
|
||||
import {
|
||||
RiSparklingFill,
|
||||
} from '@remixicon/react'
|
||||
import Button from '@/app/components/base/button'
|
||||
|
||||
export type IAutomaticBtnProps = {
|
||||
onClick: () => void
|
||||
@ -13,12 +16,10 @@ const AutomaticBtn: FC<IAutomaticBtnProps> = ({
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div className='flex space-x-1 items-center !h-8 cursor-pointer'
|
||||
onClick={onClick}
|
||||
>
|
||||
<Generator className='w-3.5 h-3.5 text-indigo-600' />
|
||||
<span className='text-xs font-semibold text-indigo-600'>{t('appDebug.operation.automatic')}</span>
|
||||
</div>
|
||||
<Button variant='secondary-accent' size='small' onClick={onClick}>
|
||||
<RiSparklingFill className='w-3.5 h-3.5 mr-1' />
|
||||
<span className=''>{t('appDebug.operation.automatic')}</span>
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
export default React.memo(AutomaticBtn)
|
||||
|
@ -38,7 +38,7 @@ import ModelName from '@/app/components/header/account-setting/model-provider-pa
|
||||
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
|
||||
export interface IGetAutomaticResProps {
|
||||
export type IGetAutomaticResProps = {
|
||||
mode: AppType
|
||||
model: Model
|
||||
isShow: boolean
|
||||
@ -54,11 +54,11 @@ const TryLabel: FC<{
|
||||
}> = ({ Icon, text, onClick }) => {
|
||||
return (
|
||||
<div
|
||||
className='mt-2 mr-1 shrink-0 flex h-7 items-center px-2 bg-gray-100 rounded-lg cursor-pointer'
|
||||
className='mt-2 mr-1 shrink-0 flex h-7 items-center px-2 bg-components-button-secondary-bg rounded-lg cursor-pointer'
|
||||
onClick={onClick}
|
||||
>
|
||||
<Icon className='w-4 h-4 text-gray-500'></Icon>
|
||||
<div className='ml-1 text-xs font-medium text-gray-700'>{text}</div>
|
||||
<Icon className='w-4 h-4 text-text-tertiary'></Icon>
|
||||
<div className='ml-1 text-xs font-medium text-text-secondary'>{text}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -140,14 +140,14 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
|
||||
const renderLoading = (
|
||||
<div className='w-0 grow flex flex-col items-center justify-center h-full space-y-3'>
|
||||
<Loading />
|
||||
<div className='text-[13px] text-gray-400'>{t('appDebug.generate.loading')}</div>
|
||||
<div className='text-[13px] text-text-tertiary'>{t('appDebug.generate.loading')}</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
const renderNoData = (
|
||||
<div className='w-0 grow flex flex-col items-center px-8 justify-center h-full space-y-3'>
|
||||
<Generator className='w-14 h-14 text-gray-300' />
|
||||
<div className='leading-5 text-center text-[13px] font-normal text-gray-400'>
|
||||
<Generator className='w-14 h-14 text-text-tertiary' />
|
||||
<div className='leading-5 text-center text-[13px] font-normal text-text-tertiary'>
|
||||
<div>{t('appDebug.generate.noDataLine1')}</div>
|
||||
<div>{t('appDebug.generate.noDataLine2')}</div>
|
||||
</div>
|
||||
@ -193,10 +193,10 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
|
||||
closable
|
||||
>
|
||||
<div className='flex h-[680px] flex-wrap'>
|
||||
<div className='w-[570px] shrink-0 p-6 h-full overflow-y-auto border-r border-gray-100'>
|
||||
<div className='w-[570px] shrink-0 p-6 h-full overflow-y-auto border-r border-divider-regular'>
|
||||
<div className='mb-8'>
|
||||
<div className={`leading-[28px] text-lg font-bold ${s.textGradient}`}>{t('appDebug.generate.title')}</div>
|
||||
<div className='mt-1 text-[13px] font-normal text-gray-500'>{t('appDebug.generate.description')}</div>
|
||||
<div className='mt-1 text-[13px] font-normal text-text-tertiary'>{t('appDebug.generate.description')}</div>
|
||||
</div>
|
||||
<div className='flex items-center mb-8'>
|
||||
<ModelIcon
|
||||
@ -213,7 +213,7 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
|
||||
</div>
|
||||
<div >
|
||||
<div className='flex items-center'>
|
||||
<div className='mr-3 shrink-0 leading-[18px] text-xs font-semibold text-gray-500 uppercase'>{t('appDebug.generate.tryIt')}</div>
|
||||
<div className='mr-3 shrink-0 leading-[18px] text-xs font-semibold text-text-tertiary uppercase'>{t('appDebug.generate.tryIt')}</div>
|
||||
<div className='grow h-px' style={{
|
||||
background: 'linear-gradient(to right, rgba(243, 244, 246, 1), rgba(243, 244, 246, 0))',
|
||||
}}></div>
|
||||
@ -232,7 +232,7 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
|
||||
{/* inputs */}
|
||||
<div className='mt-6'>
|
||||
<div className='text-[0px]'>
|
||||
<div className='mb-2 leading-5 text-sm font-medium text-gray-900'>{t('appDebug.generate.instruction')}</div>
|
||||
<div className='mb-2 leading-5 text-sm font-medium text-text-primary'>{t('appDebug.generate.instruction')}</div>
|
||||
<Textarea
|
||||
className="h-[200px] resize-none"
|
||||
placeholder={t('appDebug.generate.instructionPlaceHolder') as string}
|
||||
@ -256,7 +256,7 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
|
||||
|
||||
{(!isLoading && res) && (
|
||||
<div className='w-0 grow p-6 pb-0 h-full'>
|
||||
<div className='shrink-0 mb-3 leading-[160%] text-base font-semibold text-gray-800'>{t('appDebug.generate.resTitle')}</div>
|
||||
<div className='shrink-0 mb-3 leading-[160%] text-base font-semibold text-text-secondary'>{t('appDebug.generate.resTitle')}</div>
|
||||
<div className={cn('max-h-[555px] overflow-y-auto', !isInLLMNode && 'pb-2')}>
|
||||
<ConfigPrompt
|
||||
mode={mode}
|
||||
@ -301,7 +301,7 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className='flex justify-end py-4 bg-white'>
|
||||
<div className='flex justify-end py-4 bg-background-default'>
|
||||
<Button onClick={onClose}>{t('common.operation.cancel')}</Button>
|
||||
<Button variant='primary' className='ml-2' onClick={() => {
|
||||
setShowConfirmOverwrite(true)
|
||||
|
@ -1,5 +0,0 @@
|
||||
.modal {
|
||||
max-width: 480px !important;
|
||||
width: 480px !important;
|
||||
padding: 24px 32px !important;
|
||||
}
|
@ -3,9 +3,8 @@ import { useTranslation } from 'react-i18next'
|
||||
import Link from 'next/link'
|
||||
import dayjs from 'dayjs'
|
||||
import { RiCloseLine } from '@remixicon/react'
|
||||
import s from './index.module.css'
|
||||
import classNames from '@/utils/classnames'
|
||||
import Modal from '@/app/components/base/modal'
|
||||
import Button from '@/app/components/base/button'
|
||||
import type { LangGeniusVersionResponse } from '@/models/common'
|
||||
import { IS_CE_EDITION } from '@/config'
|
||||
import LogoSite from '@/app/components/base/logo/logo-site'
|
||||
@ -29,18 +28,18 @@ export default function AccountAbout({
|
||||
<Modal
|
||||
isShow
|
||||
onClose={() => { }}
|
||||
className={s.modal}
|
||||
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-gray-500' />
|
||||
<RiCloseLine className='w-4 h-4 text-text-tertiary' />
|
||||
</div>
|
||||
<div>
|
||||
<LogoSite className='mx-auto mb-2' />
|
||||
<div className='mb-3 text-center text-xs font-normal text-gray-500'>Version {langeniusVersionInfo?.current_version}</div>
|
||||
<div className='mb-4 text-center text-xs font-normal text-gray-700'>
|
||||
<div className='mb-3 text-center text-xs font-normal text-text-tertiary'>Version {langeniusVersionInfo?.current_version}</div>
|
||||
<div className='mb-4 text-center text-xs font-normal text-text-secondary'>
|
||||
<div>© {dayjs().year()} LangGenius, Inc., Contributors.</div>
|
||||
<div className='text-[#1C64F2]'>
|
||||
<div className='text-text-accent'>
|
||||
{
|
||||
IS_CE_EDITION
|
||||
? <Link href={'https://github.com/langgenius/dify/blob/main/LICENSE'} target='_blank' rel='noopener noreferrer'>Open Source License</Link>
|
||||
@ -52,9 +51,9 @@ export default function AccountAbout({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='mb-4 -mx-8 h-[0.5px] bg-gray-200' />
|
||||
<div className='mb-4 -mx-8 h-[0.5px] bg-divider-regular' />
|
||||
<div className='flex justify-between items-center'>
|
||||
<div className='text-xs font-medium text-gray-800'>
|
||||
<div className='text-xs font-medium text-text-primary'>
|
||||
{
|
||||
isLatest
|
||||
? t('common.about.latestAvailable', { version: langeniusVersionInfo.latest_version })
|
||||
@ -62,22 +61,24 @@ export default function AccountAbout({
|
||||
}
|
||||
</div>
|
||||
<div className='flex items-center'>
|
||||
<Link
|
||||
className={classNames(buttonClassName, 'mr-2')}
|
||||
href={'https://github.com/langgenius/dify/releases'}
|
||||
target='_blank' rel='noopener noreferrer'
|
||||
>
|
||||
{t('common.about.changeLog')}
|
||||
</Link>
|
||||
<Button className='mr-2'>
|
||||
<Link
|
||||
href={'https://github.com/langgenius/dify/releases'}
|
||||
target='_blank' rel='noopener noreferrer'
|
||||
>
|
||||
{t('common.about.changeLog')}
|
||||
</Link>
|
||||
</Button>
|
||||
{
|
||||
!isLatest && !IS_CE_EDITION && (
|
||||
<Link
|
||||
className={classNames(buttonClassName, 'text-primary-600')}
|
||||
href={langeniusVersionInfo.release_notes}
|
||||
target='_blank' rel='noopener noreferrer'
|
||||
>
|
||||
{t('common.about.updateNow')}
|
||||
</Link>
|
||||
<Button variant='primary'>
|
||||
<Link
|
||||
href={langeniusVersionInfo.release_notes}
|
||||
target='_blank' rel='noopener noreferrer'
|
||||
>
|
||||
{t('common.about.updateNow')}
|
||||
</Link>
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user