refactor(web): re-design button api (#35166)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
yyh 2026-04-14 21:22:23 +08:00 committed by GitHub
parent d4783e8c14
commit e1bbe57f9c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
444 changed files with 1636 additions and 3169 deletions

View File

@ -5,7 +5,6 @@ import { useBoolean } from 'ahooks'
import * as React from 'react'
import { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Confirm from '@/app/components/base/confirm'
import Divider from '@/app/components/base/divider'
import { LinkExternal02 } from '@/app/components/base/icons/src/vender/line/general'
@ -14,6 +13,7 @@ import {
PortalToFollowElem,
PortalToFollowElemContent,
} from '@/app/components/base/portal-to-follow-elem'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import { addTracingConfig, removeTracingConfig, updateTracingConfig } from '@/service/apps'
import { docURL } from './config'
@ -621,7 +621,7 @@ const ProviderConfigModal: FC<Props> = ({
</div>
<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-[#155EEF]"
className="flex items-center space-x-1 text-xs leading-[18px] font-normal text-[#155EEF]"
target="_blank"
href={docURL[type]}
>

View File

@ -1,5 +1,5 @@
'use client'
import type { ButtonProps } from '@/app/components/base/button'
import type { ButtonProps } from '@/app/components/base/ui/button'
import type { FormInputItem, UserAction } from '@/app/components/workflow/nodes/human-input/types'
import type { SiteInfo } from '@/models/share'
import type { HumanInputFormError } from '@/service/use-share'
@ -13,12 +13,12 @@ import * as React from 'react'
import { useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import AppIcon from '@/app/components/base/app-icon'
import Button from '@/app/components/base/button'
import ContentItem from '@/app/components/base/chat/chat/answer/human-input-content/content-item'
import ExpirationTime from '@/app/components/base/chat/chat/answer/human-input-content/expiration-time'
import { getButtonStyle } from '@/app/components/base/chat/chat/answer/human-input-content/utils'
import Loading from '@/app/components/base/loading'
import DifyLogo from '@/app/components/base/logo/dify-logo'
import { Button } from '@/app/components/base/ui/button'
import useDocumentTitle from '@/hooks/use-document-title'
import { useParams } from '@/next/navigation'
import { useGetHumanInputForm, useSubmitHumanInputForm } from '@/service/use-share'
@ -100,7 +100,7 @@ const FormContent = () => {
if (success) {
return (
<div className={cn('flex h-full w-full flex-col items-center justify-center')}>
<div className="min-w-[480px] max-w-[640px]">
<div className="max-w-[640px] min-w-[480px]">
<div className="border-components-divider-subtle flex h-[320px] flex-col gap-4 radius-3xl border bg-chat-bubble-bg p-10 pb-9 shadow-lg backdrop-blur-xs">
<div className="h-[56px] w-[56px] shrink-0 rounded-2xl border border-components-panel-border-subtle bg-background-default-dodge p-3">
<RiCheckboxCircleFill className="h-8 w-8 text-text-success" />
@ -109,7 +109,7 @@ const FormContent = () => {
<div className="title-4xl-semi-bold text-text-primary">{t('humanInput.thanks', { ns: 'share' })}</div>
<div className="title-4xl-semi-bold text-text-primary">{t('humanInput.recorded', { ns: 'share' })}</div>
</div>
<div className="system-2xs-regular-uppercase shrink-0 text-text-tertiary">{t('humanInput.submissionID', { id: token, ns: 'share' })}</div>
<div className="shrink-0 system-2xs-regular-uppercase text-text-tertiary">{t('humanInput.submissionID', { id: token, ns: 'share' })}</div>
</div>
<div className="flex flex-row-reverse px-2 py-3">
<div className={cn(
@ -128,7 +128,7 @@ const FormContent = () => {
if (expired) {
return (
<div className={cn('flex h-full w-full flex-col items-center justify-center')}>
<div className="min-w-[480px] max-w-[640px]">
<div className="max-w-[640px] min-w-[480px]">
<div className="border-components-divider-subtle flex h-[320px] flex-col gap-4 radius-3xl border bg-chat-bubble-bg p-10 pb-9 shadow-lg backdrop-blur-xs">
<div className="flex h-14 w-14 shrink-0 items-center justify-center rounded-2xl border border-components-panel-border-subtle bg-background-default-dodge p-3">
<RiInformation2Fill className="h-8 w-8 text-text-accent" />
@ -137,7 +137,7 @@ const FormContent = () => {
<div className="title-4xl-semi-bold text-text-primary">{t('humanInput.sorry', { ns: 'share' })}</div>
<div className="title-4xl-semi-bold text-text-primary">{t('humanInput.expired', { ns: 'share' })}</div>
</div>
<div className="system-2xs-regular-uppercase shrink-0 text-text-tertiary">{t('humanInput.submissionID', { id: token, ns: 'share' })}</div>
<div className="shrink-0 system-2xs-regular-uppercase text-text-tertiary">{t('humanInput.submissionID', { id: token, ns: 'share' })}</div>
</div>
<div className="flex flex-row-reverse px-2 py-3">
<div className={cn(
@ -156,7 +156,7 @@ const FormContent = () => {
if (submitted) {
return (
<div className={cn('flex h-full w-full flex-col items-center justify-center')}>
<div className="min-w-[480px] max-w-[640px]">
<div className="max-w-[640px] min-w-[480px]">
<div className="border-components-divider-subtle flex h-[320px] flex-col gap-4 radius-3xl border bg-chat-bubble-bg p-10 pb-9 shadow-lg backdrop-blur-xs">
<div className="flex h-14 w-14 shrink-0 items-center justify-center rounded-2xl border border-components-panel-border-subtle bg-background-default-dodge p-3">
<RiInformation2Fill className="h-8 w-8 text-text-accent" />
@ -165,7 +165,7 @@ const FormContent = () => {
<div className="title-4xl-semi-bold text-text-primary">{t('humanInput.sorry', { ns: 'share' })}</div>
<div className="title-4xl-semi-bold text-text-primary">{t('humanInput.completed', { ns: 'share' })}</div>
</div>
<div className="system-2xs-regular-uppercase shrink-0 text-text-tertiary">{t('humanInput.submissionID', { id: token, ns: 'share' })}</div>
<div className="shrink-0 system-2xs-regular-uppercase text-text-tertiary">{t('humanInput.submissionID', { id: token, ns: 'share' })}</div>
</div>
<div className="flex flex-row-reverse px-2 py-3">
<div className={cn(
@ -184,7 +184,7 @@ const FormContent = () => {
if (rateLimitExceeded) {
return (
<div className={cn('flex h-full w-full flex-col items-center justify-center')}>
<div className="min-w-[480px] max-w-[640px]">
<div className="max-w-[640px] min-w-[480px]">
<div className="border-components-divider-subtle flex h-[320px] flex-col gap-4 radius-3xl border bg-chat-bubble-bg p-10 pb-9 shadow-lg backdrop-blur-xs">
<div className="flex h-14 w-14 shrink-0 items-center justify-center rounded-2xl border border-components-panel-border-subtle bg-background-default-dodge p-3">
<RiErrorWarningFill className="h-8 w-8 text-text-destructive" />
@ -210,7 +210,7 @@ const FormContent = () => {
if (!formData) {
return (
<div className={cn('flex h-full w-full flex-col items-center justify-center')}>
<div className="min-w-[480px] max-w-[640px]">
<div className="max-w-[640px] min-w-[480px]">
<div className="border-components-divider-subtle flex h-[320px] flex-col gap-4 radius-3xl border bg-chat-bubble-bg p-10 pb-9 shadow-lg backdrop-blur-xs">
<div className="flex h-14 w-14 shrink-0 items-center justify-center rounded-2xl border border-components-panel-border-subtle bg-background-default-dodge p-3">
<RiErrorWarningFill className="h-8 w-8 text-text-destructive" />
@ -245,7 +245,7 @@ const FormContent = () => {
background={site.icon_background}
imageUrl={site.icon_url}
/>
<div className="system-xl-semibold grow text-text-primary">{site.title}</div>
<div className="grow system-xl-semibold text-text-primary">{site.title}</div>
</div>
<div className="h-0 w-full grow overflow-y-auto">
<div className="border-components-divider-subtle radius-3xl border bg-chat-bubble-bg p-4 shadow-lg backdrop-blur-xs">

View File

@ -2,8 +2,8 @@
import { RiArrowLeftLine, RiMailSendFill } from '@remixicon/react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import Countdown from '@/app/components/signin/countdown'
import { useLocale } from '@/context/i18n'
@ -62,9 +62,9 @@ export default function CheckCode() {
<div className="inline-flex h-14 w-14 items-center justify-center rounded-2xl border border-components-panel-border-subtle bg-background-default-dodge text-text-accent-light-mode-only shadow-lg">
<RiMailSendFill className="h-6 w-6 text-2xl" />
</div>
<div className="pb-4 pt-2">
<div className="pt-2 pb-4">
<h2 className="title-4xl-semi-bold text-text-primary">{t('checkCode.checkYourEmail', { ns: 'login' })}</h2>
<p className="body-md-regular mt-2 text-text-secondary">
<p className="mt-2 body-md-regular text-text-secondary">
<span>
{t('checkCode.tipsPrefix', { ns: 'login' })}
<strong>{email}</strong>
@ -76,7 +76,7 @@ export default function CheckCode() {
<form action="">
<input type="text" className="hidden" />
<label htmlFor="code" className="system-md-semibold mb-1 text-text-secondary">{t('checkCode.verificationCode', { ns: 'login' })}</label>
<label htmlFor="code" className="mb-1 system-md-semibold text-text-secondary">{t('checkCode.verificationCode', { ns: 'login' })}</label>
<Input value={code} onChange={e => setVerifyCode(e.target.value)} maxLength={6} className="mt-1" placeholder={t('checkCode.verificationCodePlaceholder', { ns: 'login' }) || ''} />
<Button loading={loading} disabled={loading} className="my-3 w-full" variant="primary" onClick={verify}>{t('checkCode.verify', { ns: 'login' })}</Button>
<Countdown onResend={resendCode} />
@ -88,7 +88,7 @@ export default function CheckCode() {
<div className="bg-background-default-dimm inline-block rounded-full p-1">
<RiArrowLeftLine size={12} />
</div>
<span className="system-xs-regular ml-2">{t('back', { ns: 'login' })}</span>
<span className="ml-2 system-xs-regular">{t('back', { ns: 'login' })}</span>
</div>
</div>
)

View File

@ -3,8 +3,8 @@ import { RiArrowLeftLine, RiLockPasswordLine } from '@remixicon/react'
import { noop } from 'es-toolkit/function'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import { COUNT_DOWN_KEY, COUNT_DOWN_TIME_MS } from '@/app/components/signin/countdown'
import { emailRegex } from '@/config'
@ -64,9 +64,9 @@ export default function CheckCode() {
<div className="inline-flex h-14 w-14 items-center justify-center rounded-2xl border border-components-panel-border-subtle bg-background-default-dodge shadow-lg">
<RiLockPasswordLine className="h-6 w-6 text-2xl text-text-accent-light-mode-only" />
</div>
<div className="pb-4 pt-2">
<div className="pt-2 pb-4">
<h2 className="title-4xl-semi-bold text-text-primary">{t('resetPassword', { ns: 'login' })}</h2>
<p className="body-md-regular mt-2 text-text-secondary">
<p className="mt-2 body-md-regular text-text-secondary">
{t('resetPasswordDesc', { ns: 'login' })}
</p>
</div>
@ -74,7 +74,7 @@ export default function CheckCode() {
<form onSubmit={noop}>
<input type="text" className="hidden" />
<div className="mb-2">
<label htmlFor="email" className="system-md-semibold my-2 text-text-secondary">{t('email', { ns: 'login' })}</label>
<label htmlFor="email" className="my-2 system-md-semibold text-text-secondary">{t('email', { ns: 'login' })}</label>
<div className="mt-1">
<Input id="email" type="email" disabled={loading} value={email} placeholder={t('emailPlaceholder', { ns: 'login' }) as string} onChange={e => setEmail(e.target.value)} />
</div>
@ -90,7 +90,7 @@ export default function CheckCode() {
<div className="inline-block rounded-full bg-background-default-dimmed p-1">
<RiArrowLeftLine size={12} />
</div>
<span className="system-xs-regular ml-2">{t('backToLogin', { ns: 'login' })}</span>
<span className="ml-2 system-xs-regular">{t('backToLogin', { ns: 'login' })}</span>
</Link>
</div>
)

View File

@ -3,8 +3,8 @@ import { RiCheckboxCircleFill } from '@remixicon/react'
import { useCountDown } from 'ahooks'
import { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import { validPassword } from '@/config'
import { useRouter, useSearchParams } from '@/next/navigation'
@ -91,7 +91,7 @@ const ChangePasswordForm = () => {
<h2 className="title-4xl-semi-bold text-text-primary">
{t('changePassword', { ns: 'login' })}
</h2>
<p className="body-md-regular mt-2 text-text-secondary">
<p className="mt-2 body-md-regular text-text-secondary">
{t('changePasswordTip', { ns: 'login' })}
</p>
</div>
@ -100,7 +100,7 @@ const ChangePasswordForm = () => {
<div className="bg-white">
{/* Password */}
<div className="mb-5">
<label htmlFor="password" className="system-md-semibold my-2 text-text-secondary">
<label htmlFor="password" className="my-2 system-md-semibold text-text-secondary">
{t('account.newPassword', { ns: 'common' })}
</label>
<div className="relative mt-1">
@ -122,11 +122,11 @@ const ChangePasswordForm = () => {
</Button>
</div>
</div>
<div className="body-xs-regular mt-1 text-text-secondary">{t('error.passwordInvalid', { ns: 'login' })}</div>
<div className="mt-1 body-xs-regular text-text-secondary">{t('error.passwordInvalid', { ns: 'login' })}</div>
</div>
{/* Confirm Password */}
<div className="mb-5">
<label htmlFor="confirmPassword" className="system-md-semibold my-2 text-text-secondary">
<label htmlFor="confirmPassword" className="my-2 system-md-semibold text-text-secondary">
{t('account.confirmPassword', { ns: 'common' })}
</label>
<div className="relative mt-1">

View File

@ -3,8 +3,8 @@ import type { FormEvent } from 'react'
import { RiArrowLeftLine, RiMailSendFill } from '@remixicon/react'
import { useCallback, useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import Countdown from '@/app/components/signin/countdown'
import { useLocale } from '@/context/i18n'
@ -100,9 +100,9 @@ export default function CheckCode() {
<div className="inline-flex h-14 w-14 items-center justify-center rounded-2xl border border-components-panel-border-subtle bg-background-default-dodge shadow-lg">
<RiMailSendFill className="h-6 w-6 text-2xl text-text-accent-light-mode-only" />
</div>
<div className="pb-4 pt-2">
<div className="pt-2 pb-4">
<h2 className="title-4xl-semi-bold text-text-primary">{t('checkCode.checkYourEmail', { ns: 'login' })}</h2>
<p className="body-md-regular mt-2 text-text-secondary">
<p className="mt-2 body-md-regular text-text-secondary">
<span>
{t('checkCode.tipsPrefix', { ns: 'login' })}
<strong>{email}</strong>
@ -113,7 +113,7 @@ export default function CheckCode() {
</div>
<form onSubmit={handleSubmit}>
<label htmlFor="code" className="system-md-semibold mb-1 text-text-secondary">{t('checkCode.verificationCode', { ns: 'login' })}</label>
<label htmlFor="code" className="mb-1 system-md-semibold text-text-secondary">{t('checkCode.verificationCode', { ns: 'login' })}</label>
<Input
ref={codeInputRef}
id="code"
@ -133,7 +133,7 @@ export default function CheckCode() {
<div className="bg-background-default-dimm inline-block rounded-full p-1">
<RiArrowLeftLine size={12} />
</div>
<span className="system-xs-regular ml-2">{t('back', { ns: 'login' })}</span>
<span className="ml-2 system-xs-regular">{t('back', { ns: 'login' })}</span>
</div>
</div>
)

View File

@ -1,8 +1,8 @@
import { noop } from 'es-toolkit/function'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import { COUNT_DOWN_KEY, COUNT_DOWN_TIME_MS } from '@/app/components/signin/countdown'
import { emailRegex } from '@/config'
@ -52,7 +52,7 @@ export default function MailAndCodeAuth() {
<form onSubmit={noop}>
<input type="text" className="hidden" />
<div className="mb-2">
<label htmlFor="email" className="system-md-semibold my-2 text-text-secondary">{t('email', { ns: 'login' })}</label>
<label htmlFor="email" className="my-2 system-md-semibold text-text-secondary">{t('email', { ns: 'login' })}</label>
<div className="mt-1">
<Input id="email" type="email" value={email} placeholder={t('emailPlaceholder', { ns: 'login' }) as string} onChange={e => setEmail(e.target.value)} />
</div>

View File

@ -2,8 +2,8 @@
import { noop } from 'es-toolkit/function'
import { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import { emailRegex } from '@/config'
import { useLocale } from '@/context/i18n'
@ -103,7 +103,7 @@ export default function MailAndPasswordAuth({ isEmailSetup }: MailAndPasswordAut
return (
<form onSubmit={noop}>
<div className="mb-3">
<label htmlFor="email" className="system-md-semibold my-2 text-text-secondary">
<label htmlFor="email" className="my-2 system-md-semibold text-text-secondary">
{t('email', { ns: 'login' })}
</label>
<div className="mt-1">

View File

@ -2,8 +2,8 @@
import type { FC } from 'react'
import { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import { Lock01 } from '@/app/components/base/icons/src/vender/solid/security'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import { useRouter, useSearchParams } from '@/next/navigation'
import { fetchMembersOAuth2SSOUrl, fetchMembersOIDCSSOUrl, fetchMembersSAMLSSOUrl } from '@/service/share'

View File

@ -10,10 +10,10 @@ import { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import ImageInput from '@/app/components/base/app-icon-picker/ImageInput'
import getCroppedImg from '@/app/components/base/app-icon-picker/utils'
import Button from '@/app/components/base/button'
import Divider from '@/app/components/base/divider'
import { useLocalFileUploader } from '@/app/components/base/image-uploader/hooks'
import { Avatar } from '@/app/components/base/ui/avatar'
import { Button } from '@/app/components/base/ui/button'
import { Dialog, DialogContent } from '@/app/components/base/ui/dialog'
import { toast } from '@/app/components/base/ui/toast'
import { DISABLE_UPLOAD_IMAGE_AS_ICON } from '@/config'
@ -151,7 +151,7 @@ const AvatarWithEdit = ({ onSave, ...props }: AvatarWithEditProps) => {
<Dialog open={isShowDeleteConfirm} onOpenChange={open => !open && setIsShowDeleteConfirm(false)}>
<DialogContent className="w-[362px]! p-6!">
<div className="mb-3 text-text-primary title-2xl-semi-bold">{t('avatar.deleteTitle', { ns: 'common' })}</div>
<div className="mb-3 title-2xl-semi-bold text-text-primary">{t('avatar.deleteTitle', { ns: 'common' })}</div>
<p className="mb-8 text-text-secondary">{t('avatar.deleteDescription', { ns: 'common' })}</p>
<div className="flex w-full items-center justify-center gap-2">
@ -159,7 +159,7 @@ const AvatarWithEdit = ({ onSave, ...props }: AvatarWithEditProps) => {
{t('operation.cancel', { ns: 'common' })}
</Button>
<Button variant="warning" className="w-full" onClick={handleDeleteAvatar}>
<Button variant="primary" destructive className="w-full" onClick={handleDeleteAvatar}>
{t('operation.delete', { ns: 'common' })}
</Button>
</div>

View File

@ -3,8 +3,8 @@ import { RiCloseLine } from '@remixicon/react'
import * as React from 'react'
import { useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
import { Button } from '@/app/components/base/ui/button'
import { Dialog, DialogContent } from '@/app/components/base/ui/dialog'
import { toast } from '@/app/components/base/ui/toast'
import { useRouter } from '@/next/navigation'
@ -183,19 +183,19 @@ const EmailChangeModal = ({ onClose, email, show }: Props) => {
return (
<Dialog open={show} onOpenChange={open => !open && onClose()}>
<DialogContent className="w-[420px]! p-6!">
<div className="absolute right-5 top-5 cursor-pointer p-1.5" onClick={onClose}>
<div className="absolute top-5 right-5 cursor-pointer p-1.5" onClick={onClose}>
<RiCloseLine className="h-5 w-5 text-text-tertiary" />
</div>
{step === STEP.start && (
<>
<div className="pb-3 text-text-primary title-2xl-semi-bold">{t('account.changeEmail.title', { ns: 'common' })}</div>
<div className="space-y-0.5 pb-2 pt-1">
<div className="text-text-warning body-md-medium">{t('account.changeEmail.authTip', { ns: 'common' })}</div>
<div className="text-text-secondary body-md-regular">
<div className="pb-3 title-2xl-semi-bold text-text-primary">{t('account.changeEmail.title', { ns: 'common' })}</div>
<div className="space-y-0.5 pt-1 pb-2">
<div className="body-md-medium text-text-warning">{t('account.changeEmail.authTip', { ns: 'common' })}</div>
<div className="body-md-regular text-text-secondary">
<Trans
i18nKey="account.changeEmail.content1"
ns="common"
components={{ email: <span className="text-text-primary body-md-medium"></span> }}
components={{ email: <span className="body-md-medium text-text-primary"></span> }}
values={{ email }}
/>
</div>
@ -220,19 +220,19 @@ const EmailChangeModal = ({ onClose, email, show }: Props) => {
)}
{step === STEP.verifyOrigin && (
<>
<div className="pb-3 text-text-primary title-2xl-semi-bold">{t('account.changeEmail.verifyEmail', { ns: 'common' })}</div>
<div className="space-y-0.5 pb-2 pt-1">
<div className="text-text-secondary body-md-regular">
<div className="pb-3 title-2xl-semi-bold text-text-primary">{t('account.changeEmail.verifyEmail', { ns: 'common' })}</div>
<div className="space-y-0.5 pt-1 pb-2">
<div className="body-md-regular text-text-secondary">
<Trans
i18nKey="account.changeEmail.content2"
ns="common"
components={{ email: <span className="text-text-primary body-md-medium"></span> }}
components={{ email: <span className="body-md-medium text-text-primary"></span> }}
values={{ email }}
/>
</div>
</div>
<div className="pt-3">
<div className="mb-1 flex h-6 items-center text-text-secondary system-sm-medium">{t('account.changeEmail.codeLabel', { ns: 'common' })}</div>
<div className="mb-1 flex h-6 items-center system-sm-medium text-text-secondary">{t('account.changeEmail.codeLabel', { ns: 'common' })}</div>
<Input
className="w-full!"
placeholder={t('account.changeEmail.codePlaceholder', { ns: 'common' })}
@ -257,25 +257,25 @@ const EmailChangeModal = ({ onClose, email, show }: Props) => {
{t('operation.cancel', { ns: 'common' })}
</Button>
</div>
<div className="mt-3 flex items-center gap-1 text-text-tertiary system-xs-regular">
<div className="mt-3 flex items-center gap-1 system-xs-regular text-text-tertiary">
<span>{t('account.changeEmail.resendTip', { ns: 'common' })}</span>
{time > 0 && (
<span>{t('account.changeEmail.resendCount', { ns: 'common', count: time })}</span>
)}
{!time && (
<span onClick={sendCodeToOriginEmail} className="cursor-pointer text-text-accent-secondary system-xs-medium">{t('account.changeEmail.resend', { ns: 'common' })}</span>
<span onClick={sendCodeToOriginEmail} className="cursor-pointer system-xs-medium text-text-accent-secondary">{t('account.changeEmail.resend', { ns: 'common' })}</span>
)}
</div>
</>
)}
{step === STEP.newEmail && (
<>
<div className="pb-3 text-text-primary title-2xl-semi-bold">{t('account.changeEmail.newEmail', { ns: 'common' })}</div>
<div className="space-y-0.5 pb-2 pt-1">
<div className="text-text-secondary body-md-regular">{t('account.changeEmail.content3', { ns: 'common' })}</div>
<div className="pb-3 title-2xl-semi-bold text-text-primary">{t('account.changeEmail.newEmail', { ns: 'common' })}</div>
<div className="space-y-0.5 pt-1 pb-2">
<div className="body-md-regular text-text-secondary">{t('account.changeEmail.content3', { ns: 'common' })}</div>
</div>
<div className="pt-3">
<div className="mb-1 flex h-6 items-center text-text-secondary system-sm-medium">{t('account.changeEmail.emailLabel', { ns: 'common' })}</div>
<div className="mb-1 flex h-6 items-center system-sm-medium text-text-secondary">{t('account.changeEmail.emailLabel', { ns: 'common' })}</div>
<Input
className="w-full!"
placeholder={t('account.changeEmail.emailPlaceholder', { ns: 'common' })}
@ -284,10 +284,10 @@ const EmailChangeModal = ({ onClose, email, show }: Props) => {
destructive={newEmailExited || unAvailableEmail}
/>
{newEmailExited && (
<div className="mt-1 py-0.5 text-text-destructive body-xs-regular">{t('account.changeEmail.existingEmail', { ns: 'common' })}</div>
<div className="mt-1 py-0.5 body-xs-regular text-text-destructive">{t('account.changeEmail.existingEmail', { ns: 'common' })}</div>
)}
{unAvailableEmail && (
<div className="mt-1 py-0.5 text-text-destructive body-xs-regular">{t('account.changeEmail.unAvailableEmail', { ns: 'common' })}</div>
<div className="mt-1 py-0.5 body-xs-regular text-text-destructive">{t('account.changeEmail.unAvailableEmail', { ns: 'common' })}</div>
)}
</div>
<div className="mt-3 space-y-2">
@ -310,19 +310,19 @@ const EmailChangeModal = ({ onClose, email, show }: Props) => {
)}
{step === STEP.verifyNew && (
<>
<div className="pb-3 text-text-primary title-2xl-semi-bold">{t('account.changeEmail.verifyNew', { ns: 'common' })}</div>
<div className="space-y-0.5 pb-2 pt-1">
<div className="text-text-secondary body-md-regular">
<div className="pb-3 title-2xl-semi-bold text-text-primary">{t('account.changeEmail.verifyNew', { ns: 'common' })}</div>
<div className="space-y-0.5 pt-1 pb-2">
<div className="body-md-regular text-text-secondary">
<Trans
i18nKey="account.changeEmail.content4"
ns="common"
components={{ email: <span className="text-text-primary body-md-medium"></span> }}
components={{ email: <span className="body-md-medium text-text-primary"></span> }}
values={{ email: mail }}
/>
</div>
</div>
<div className="pt-3">
<div className="mb-1 flex h-6 items-center text-text-secondary system-sm-medium">{t('account.changeEmail.codeLabel', { ns: 'common' })}</div>
<div className="mb-1 flex h-6 items-center system-sm-medium text-text-secondary">{t('account.changeEmail.codeLabel', { ns: 'common' })}</div>
<Input
className="w-full!"
placeholder={t('account.changeEmail.codePlaceholder', { ns: 'common' })}
@ -347,13 +347,13 @@ const EmailChangeModal = ({ onClose, email, show }: Props) => {
{t('operation.cancel', { ns: 'common' })}
</Button>
</div>
<div className="mt-3 flex items-center gap-1 text-text-tertiary system-xs-regular">
<div className="mt-3 flex items-center gap-1 system-xs-regular text-text-tertiary">
<span>{t('account.changeEmail.resendTip', { ns: 'common' })}</span>
{time > 0 && (
<span>{t('account.changeEmail.resendCount', { ns: 'common', count: time })}</span>
)}
{!time && (
<span onClick={sendCodeToNewEmail} className="cursor-pointer text-text-accent-secondary system-xs-medium">{t('account.changeEmail.resend', { ns: 'common' })}</span>
<span onClick={sendCodeToNewEmail} className="cursor-pointer system-xs-medium text-text-accent-secondary">{t('account.changeEmail.resend', { ns: 'common' })}</span>
)}
</div>
</>

View File

@ -8,9 +8,9 @@ import { useQueryClient } from '@tanstack/react-query'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import AppIcon from '@/app/components/base/app-icon'
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
import PremiumBadge from '@/app/components/base/premium-badge'
import { Button } from '@/app/components/base/ui/button'
import { Dialog, DialogContent } from '@/app/components/base/ui/dialog'
import { toast } from '@/app/components/base/ui/toast'
import Collapse from '@/app/components/header/account-setting/collapse'
@ -140,20 +140,20 @@ export default function AccountPage() {
imageUrl={icon_url}
/>
</div>
<div className="mt-[3px] text-text-secondary system-sm-medium">{item.name}</div>
<div className="mt-[3px] system-sm-medium text-text-secondary">{item.name}</div>
</div>
)
}
return (
<>
<div className="pb-3 pt-2">
<h4 className="text-text-primary title-2xl-semi-bold">{t('account.myAccount', { ns: 'common' })}</h4>
<div className="pt-2 pb-3">
<h4 className="title-2xl-semi-bold text-text-primary">{t('account.myAccount', { ns: 'common' })}</h4>
</div>
<div className="mb-8 flex items-center rounded-xl bg-gradient-to-r from-background-gradient-bg-fill-chat-bg-2 to-background-gradient-bg-fill-chat-bg-1 p-6">
<AvatarWithEdit avatar={userProfile.avatar_url} name={userProfile.name} onSave={mutateUserProfile} size="3xl" />
<div className="ml-4">
<p className="text-text-primary system-xl-semibold">
<p className="system-xl-semibold text-text-primary">
{userProfile.name}
{isEducationAccount && (
<PremiumBadge size="s" color="blue" className="ml-1 !px-2">
@ -162,16 +162,16 @@ export default function AccountPage() {
</PremiumBadge>
)}
</p>
<p className="text-text-tertiary system-xs-regular">{userProfile.email}</p>
<p className="system-xs-regular text-text-tertiary">{userProfile.email}</p>
</div>
</div>
<div className="mb-8">
<div className={titleClassName}>{t('account.name', { ns: 'common' })}</div>
<div className="mt-2 flex w-full items-center justify-between gap-2">
<div className="flex-1 rounded-lg bg-components-input-bg-normal p-2 text-components-input-text-filled system-sm-regular">
<div className="flex-1 rounded-lg bg-components-input-bg-normal p-2 system-sm-regular text-components-input-text-filled">
<span className="pl-1">{userProfile.name}</span>
</div>
<div className="cursor-pointer rounded-lg bg-components-button-tertiary-bg px-3 py-2 text-components-button-tertiary-text system-sm-medium" onClick={handleEditName}>
<div className="cursor-pointer rounded-lg bg-components-button-tertiary-bg px-3 py-2 system-sm-medium text-components-button-tertiary-text" onClick={handleEditName}>
{t('operation.edit', { ns: 'common' })}
</div>
</div>
@ -179,11 +179,11 @@ export default function AccountPage() {
<div className="mb-8">
<div className={titleClassName}>{t('account.email', { ns: 'common' })}</div>
<div className="mt-2 flex w-full items-center justify-between gap-2">
<div className="flex-1 rounded-lg bg-components-input-bg-normal p-2 text-components-input-text-filled system-sm-regular">
<div className="flex-1 rounded-lg bg-components-input-bg-normal p-2 system-sm-regular text-components-input-text-filled">
<span className="pl-1">{userProfile.email}</span>
</div>
{systemFeatures.enable_change_email && (
<div className="cursor-pointer rounded-lg bg-components-button-tertiary-bg px-3 py-2 text-components-button-tertiary-text system-sm-medium" onClick={() => setShowUpdateEmail(true)}>
<div className="cursor-pointer rounded-lg bg-components-button-tertiary-bg px-3 py-2 system-sm-medium text-components-button-tertiary-text" onClick={() => setShowUpdateEmail(true)}>
{t('operation.change', { ns: 'common' })}
</div>
)}
@ -193,8 +193,8 @@ export default function AccountPage() {
systemFeatures.enable_email_password_login && (
<div className="mb-8 flex justify-between gap-2">
<div>
<div className="mb-1 text-text-secondary system-sm-semibold">{t('account.password', { ns: 'common' })}</div>
<div className="mb-2 text-text-tertiary body-xs-regular">{t('account.passwordTip', { ns: 'common' })}</div>
<div className="mb-1 system-sm-semibold text-text-secondary">{t('account.password', { ns: 'common' })}</div>
<div className="mb-2 body-xs-regular text-text-tertiary">{t('account.passwordTip', { ns: 'common' })}</div>
</div>
<Button onClick={() => setEditPasswordModalVisible(true)}>{userProfile.is_password_set ? t('account.resetPassword', { ns: 'common' }) : t('account.setPassword', { ns: 'common' })}</Button>
</div>
@ -218,7 +218,7 @@ export default function AccountPage() {
editNameModalVisible && (
<Dialog open={editNameModalVisible} onOpenChange={open => !open && setEditNameModalVisible(false)}>
<DialogContent className="w-[420px]! p-6!">
<div className="mb-6 text-text-primary title-2xl-semi-bold">{t('account.editName', { ns: 'common' })}</div>
<div className="mb-6 title-2xl-semi-bold text-text-primary">{t('account.editName', { ns: 'common' })}</div>
<div className={titleClassName}>{t('account.name', { ns: 'common' })}</div>
<Input
className="mt-2"
@ -243,7 +243,7 @@ export default function AccountPage() {
editPasswordModalVisible && (
<Dialog open={editPasswordModalVisible} onOpenChange={open => !open && (setEditPasswordModalVisible(false), resetPasswordForm())}>
<DialogContent className="w-[420px]! p-6!">
<div className="mb-6 text-text-primary title-2xl-semi-bold">{userProfile.is_password_set ? t('account.resetPassword', { ns: 'common' }) : t('account.setPassword', { ns: 'common' })}</div>
<div className="mb-6 title-2xl-semi-bold text-text-primary">{userProfile.is_password_set ? t('account.resetPassword', { ns: 'common' }) : t('account.setPassword', { ns: 'common' })}</div>
{userProfile.is_password_set && (
<>
<div className={titleClassName}>{t('account.currentPassword', { ns: 'common' })}</div>
@ -266,7 +266,7 @@ export default function AccountPage() {
</div>
</>
)}
<div className="mt-8 text-text-secondary system-sm-semibold">
<div className="mt-8 system-sm-semibold text-text-secondary">
{userProfile.is_password_set ? t('account.newPassword', { ns: 'common' }) : t('account.password', { ns: 'common' })}
</div>
<div className="relative mt-2">
@ -285,7 +285,7 @@ export default function AccountPage() {
</Button>
</div>
</div>
<div className="mt-8 text-text-secondary system-sm-semibold">{t('account.confirmPassword', { ns: 'common' })}</div>
<div className="mt-8 system-sm-semibold text-text-secondary">{t('account.confirmPassword', { ns: 'common' })}</div>
<div className="relative mt-2">
<Input
type={showConfirmPassword ? 'text' : 'password'}

View File

@ -1,8 +1,8 @@
'use client'
import { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
import { Button } from '@/app/components/base/ui/button'
import { useAppContext } from '@/context/app-context'
import Link from '@/next/link'
import { useSendDeleteAccountEmail } from '../state'
@ -30,14 +30,14 @@ export default function CheckEmail(props: DeleteAccountProps) {
return (
<>
<div className="body-md-medium py-1 text-text-destructive">
<div className="py-1 body-md-medium text-text-destructive">
{t('account.deleteTip', { ns: 'common' })}
</div>
<div className="body-md-regular pb-2 pt-1 text-text-secondary">
<div className="pt-1 pb-2 body-md-regular text-text-secondary">
{t('account.deletePrivacyLinkTip', { ns: 'common' })}
<Link href="https://dify.ai/privacy" className="text-text-accent">{t('account.deletePrivacyLink', { ns: 'common' })}</Link>
</div>
<label className="system-sm-semibold mb-1 mt-3 flex h-6 items-center text-text-secondary">{t('account.deleteLabel', { ns: 'common' })}</label>
<label className="mt-3 mb-1 flex h-6 items-center system-sm-semibold text-text-secondary">{t('account.deleteLabel', { ns: 'common' })}</label>
<Input
placeholder={t('account.deletePlaceholder', { ns: 'common' }) as string}
onChange={(e) => {

View File

@ -1,9 +1,9 @@
'use client'
import { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import CustomDialog from '@/app/components/base/dialog'
import Textarea from '@/app/components/base/textarea'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import { useAppContext } from '@/context/app-context'
import { useRouter } from '@/next/navigation'
@ -54,7 +54,7 @@ export default function FeedBack(props: DeleteAccountProps) {
className="max-w-[480px]"
footer={false}
>
<label className="system-sm-semibold mb-1 mt-3 flex items-center text-text-secondary">{t('account.feedbackLabel', { ns: 'common' })}</label>
<label className="mt-3 mb-1 flex items-center system-sm-semibold text-text-secondary">{t('account.feedbackLabel', { ns: 'common' })}</label>
<Textarea
rows={6}
value={userFeedback}

View File

@ -1,8 +1,8 @@
'use client'
import { useCallback, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
import { Button } from '@/app/components/base/ui/button'
import Countdown from '@/app/components/signin/countdown'
import Link from '@/next/link'
import { useAccountDeleteStore, useConfirmDeleteAccount, useSendDeleteAccountEmail } from '../state'
@ -36,14 +36,14 @@ export default function VerifyEmail(props: DeleteAccountProps) {
}, [emailToken, verificationCode, confirmDeleteAccount, props])
return (
<>
<div className="body-md-medium pt-1 text-text-destructive">
<div className="pt-1 body-md-medium text-text-destructive">
{t('account.deleteTip', { ns: 'common' })}
</div>
<div className="body-md-regular pb-2 pt-1 text-text-secondary">
<div className="pt-1 pb-2 body-md-regular text-text-secondary">
{t('account.deletePrivacyLinkTip', { ns: 'common' })}
<Link href="https://dify.ai/privacy" className="text-text-accent">{t('account.deletePrivacyLink', { ns: 'common' })}</Link>
</div>
<label className="system-sm-semibold mb-1 mt-3 flex h-6 items-center text-text-secondary">{t('account.verificationLabel', { ns: 'common' })}</label>
<label className="mt-3 mb-1 flex h-6 items-center system-sm-semibold text-text-secondary">{t('account.verificationLabel', { ns: 'common' })}</label>
<Input
minLength={6}
maxLength={6}
@ -53,7 +53,7 @@ export default function VerifyEmail(props: DeleteAccountProps) {
}}
/>
<div className="mt-3 flex w-full flex-col gap-2">
<Button className="w-full" disabled={shouldButtonDisabled} loading={isDeleting} variant="warning" onClick={handleConfirm}>{t('account.permanentlyDeleteButton', { ns: 'common' })}</Button>
<Button className="w-full" disabled={shouldButtonDisabled} loading={isDeleting} variant="primary" destructive onClick={handleConfirm}>{t('account.permanentlyDeleteButton', { ns: 'common' })}</Button>
<Button className="w-full" onClick={props.onCancel}>{t('operation.cancel', { ns: 'common' })}</Button>
<Countdown onResend={sendEmail} />
</div>

View File

@ -2,8 +2,8 @@
import { RiArrowRightUpLine, RiRobot2Line } from '@remixicon/react'
import { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import DifyLogo from '@/app/components/base/logo/dify-logo'
import { Button } from '@/app/components/base/ui/button'
import { useGlobalPublicStore } from '@/context/global-public-context'
import { useRouter } from '@/next/navigation'
import Avatar from './avatar'
@ -32,10 +32,10 @@ const Header = () => {
: <DifyLogo />}
</div>
<div className="h-4 w-px origin-center rotate-[11.31deg] bg-divider-regular" />
<p className="title-3xl-semi-bold relative mt-[-2px] text-text-primary">{t('account.account', { ns: 'common' })}</p>
<p className="relative mt-[-2px] title-3xl-semi-bold text-text-primary">{t('account.account', { ns: 'common' })}</p>
</div>
<div className="flex shrink-0 items-center gap-3">
<Button className="system-sm-medium gap-2 px-3 py-2" onClick={goToStudio}>
<Button className="gap-2 px-3 py-2 system-sm-medium" onClick={goToStudio}>
<RiRobot2Line className="h-4 w-4" />
<p>{t('account.studio', { ns: 'common' })}</p>
<RiArrowRightUpLine className="h-4 w-4" />

View File

@ -10,9 +10,9 @@ import {
import * as React from 'react'
import { useEffect, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Loading from '@/app/components/base/loading'
import { Avatar } from '@/app/components/base/ui/avatar'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks'
import { setPostLoginRedirect } from '@/app/signin/utils/post-login-redirect'
@ -122,13 +122,13 @@ export default function OAuthAuthorize() {
</div>
)}
<div className={`mb-4 mt-5 flex flex-col gap-2 ${isLoggedIn ? 'pb-2' : ''}`}>
<div className={`mt-5 mb-4 flex flex-col gap-2 ${isLoggedIn ? 'pb-2' : ''}`}>
<div className="title-4xl-semi-bold">
{isLoggedIn && <div className="text-text-primary">{t('connect', { ns: 'oauth' })}</div>}
<div className="text-(--color-saas-dify-blue-inverted)">{authAppInfo?.app_label[language] || authAppInfo?.app_label?.en_US || t('unknownApp', { ns: 'oauth' })}</div>
{!isLoggedIn && <div className="text-text-primary">{t('tips.notLoggedIn', { ns: 'oauth' })}</div>}
</div>
<div className="text-text-secondary body-md-regular">{isLoggedIn ? `${authAppInfo?.app_label[language] || authAppInfo?.app_label?.en_US || t('unknownApp', { ns: 'oauth' })} ${t('tips.loggedIn', { ns: 'oauth' })}` : t('tips.needLogin', { ns: 'oauth' })}</div>
<div className="body-md-regular text-text-secondary">{isLoggedIn ? `${authAppInfo?.app_label[language] || authAppInfo?.app_label?.en_US || t('unknownApp', { ns: 'oauth' })} ${t('tips.loggedIn', { ns: 'oauth' })}` : t('tips.needLogin', { ns: 'oauth' })}</div>
</div>
{isLoggedIn && userProfile && (
@ -137,7 +137,7 @@ export default function OAuthAuthorize() {
<Avatar avatar={userProfile.avatar_url} name={userProfile.name} size="lg" />
<div>
<div className="system-md-semi-bold text-text-secondary">{userProfile.name}</div>
<div className="text-text-tertiary system-xs-regular">{userProfile.email}</div>
<div className="system-xs-regular text-text-tertiary">{userProfile.email}</div>
</div>
</div>
<Button variant="tertiary" size="small" onClick={onLoginSwitchClick}>{t('switchAccount', { ns: 'oauth' })}</Button>
@ -149,7 +149,7 @@ export default function OAuthAuthorize() {
{authAppInfo!.scope.split(/\s+/).filter(Boolean).map((scope: string) => {
const Icon = SCOPE_INFO_MAP[scope]
return (
<div key={scope} className="flex items-center gap-2 text-text-secondary body-sm-medium">
<div key={scope} className="flex items-center gap-2 body-sm-medium text-text-secondary">
{Icon ? <Icon.icon className="h-4 w-4" /> : <RiAccountCircleLine className="h-4 w-4" />}
{Icon.label}
</div>
@ -182,7 +182,7 @@ export default function OAuthAuthorize() {
</defs>
</svg>
</div>
<div className="mt-3 text-text-tertiary system-xs-regular">{t('tips.common', { ns: 'oauth' })}</div>
<div className="mt-3 system-xs-regular text-text-tertiary">{t('tips.common', { ns: 'oauth' })}</div>
</div>
)
}

View File

@ -1,8 +1,8 @@
'use client'
import { useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Loading from '@/app/components/base/loading'
import { Button } from '@/app/components/base/ui/button'
import useDocumentTitle from '@/hooks/use-document-title'
import { useRouter, useSearchParams } from '@/next/navigation'

View File

@ -35,8 +35,8 @@ vi.mock('@/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/card-view',
),
}))
vi.mock('@/app/components/base/button', () => ({
default: ({ children, onClick, className, size, variant }: {
vi.mock('@/app/components/base/ui/button', () => ({
Button: ({ children, onClick, className, size, variant }: {
children: React.ReactNode
onClick?: () => void
className?: string

View File

@ -4,8 +4,8 @@ import userEvent from '@testing-library/user-event'
import * as React from 'react'
import AppOperations from '../app-operations'
vi.mock('../../../base/button', () => ({
default: ({ children, onClick, className, size, variant, id, tabIndex, ...rest }: {
vi.mock('../../../base/ui/button', () => ({
Button: ({ children, onClick, className, size, variant, id, tabIndex, ...rest }: {
'children': React.ReactNode
'onClick'?: () => void
'className'?: string

View File

@ -13,8 +13,8 @@ import * as React from 'react'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import CardView from '@/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/card-view'
import Button from '@/app/components/base/button'
import ContentDialog from '@/app/components/base/content-dialog'
import { Button } from '@/app/components/base/ui/button'
import { AppModeEnum } from '@/types/app'
import AppIcon from '../../base/app-icon'
import { getAppModeLabel } from './app-mode-labels'
@ -97,7 +97,7 @@ const AppInfoDetailPanel = ({
<ContentDialog
show={show}
onClose={onClose}
className="absolute bottom-2 left-2 top-2 flex w-[420px] flex-col rounded-2xl p-0!"
className="absolute top-2 bottom-2 left-2 flex w-[420px] flex-col rounded-2xl p-0!"
>
<div className="flex shrink-0 flex-col items-start justify-center gap-3 self-stretch p-4">
<div className="flex items-center gap-3 self-stretch">
@ -109,14 +109,14 @@ const AppInfoDetailPanel = ({
imageUrl={appDetail.icon_url}
/>
<div className="flex flex-1 flex-col items-start justify-center overflow-hidden">
<div className="w-full truncate text-text-secondary system-md-semibold">{appDetail.name}</div>
<div className="text-text-tertiary system-2xs-medium-uppercase">
<div className="w-full truncate system-md-semibold text-text-secondary">{appDetail.name}</div>
<div className="system-2xs-medium-uppercase text-text-tertiary">
{getAppModeLabel(appDetail.mode, t)}
</div>
</div>
</div>
{appDetail.description && (
<div className="overflow-wrap-anywhere max-h-[105px] w-full max-w-full overflow-y-auto whitespace-normal wrap-break-word text-text-tertiary system-xs-regular">
<div className="overflow-wrap-anywhere max-h-[105px] w-full max-w-full overflow-y-auto system-xs-regular wrap-break-word whitespace-normal text-text-tertiary">
{appDetail.description}
</div>
)}
@ -140,7 +140,7 @@ const AppInfoDetailPanel = ({
onClick={switchOperation.onClick}
>
{switchOperation.icon}
<span className="text-text-tertiary system-sm-medium">{switchOperation.title}</span>
<span className="system-sm-medium text-text-tertiary">{switchOperation.title}</span>
</Button>
</div>
)}

View File

@ -2,7 +2,7 @@ import type { JSX } from 'react'
import { RiMoreLine } from '@remixicon/react'
import { cloneElement, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import { Button } from '@/app/components/base/ui/button'
import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger } from '../../base/portal-to-follow-elem'
export type Operation = {
@ -134,7 +134,7 @@ const AppOperations = ({
tabIndex={-1}
>
{cloneElement(operation.icon, { className: 'h-3.5 w-3.5 text-components-button-secondary-text' })}
<span className="text-components-button-secondary-text system-xs-medium">
<span className="system-xs-medium text-components-button-secondary-text">
{operation.title}
</span>
</Button>
@ -147,7 +147,7 @@ const AppOperations = ({
tabIndex={-1}
>
<RiMoreLine className="h-3.5 w-3.5 text-components-button-secondary-text" />
<span className="text-components-button-secondary-text system-xs-medium">
<span className="system-xs-medium text-components-button-secondary-text">
{t('operation.more', { ns: 'common' })}
</span>
</Button>
@ -163,7 +163,7 @@ const AppOperations = ({
onClick={operation.onClick}
>
{cloneElement(operation.icon, { className: 'h-3.5 w-3.5 text-components-button-secondary-text' })}
<span className="text-components-button-secondary-text system-xs-medium">
<span className="system-xs-medium text-components-button-secondary-text">
{operation.title}
</span>
</Button>
@ -182,7 +182,7 @@ const AppOperations = ({
className="gap-px"
>
<RiMoreLine className="h-3.5 w-3.5 text-components-button-secondary-text" />
<span className="text-components-button-secondary-text system-xs-medium">
<span className="system-xs-medium text-components-button-secondary-text">
{t('operation.more', { ns: 'common' })}
</span>
</Button>
@ -200,7 +200,7 @@ const AppOperations = ({
onClick={item.onClick}
>
{cloneElement(item.icon, { className: 'h-4 w-4 text-text-tertiary' })}
<span className="text-text-secondary system-md-regular">{item.title}</span>
<span className="system-md-regular text-text-secondary">{item.title}</span>
</div>
))}
</div>

View File

@ -1,8 +1,8 @@
import { RiArrowLeftSLine, RiArrowRightSLine } from '@remixicon/react'
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import { Button } from '@/app/components/base/ui/button'
import { cn } from '@/utils/classnames'
import Button from '../base/button'
import Tooltip from '../base/tooltip'
import ShortcutsName from '../workflow/shortcuts-name'
@ -19,7 +19,7 @@ const TooltipContent = ({
return (
<div className="flex items-center gap-x-1">
<span className="px-0.5 text-text-secondary system-xs-medium">{expand ? t('sidebar.collapseSidebar', { ns: 'layout' }) : t('sidebar.expandSidebar', { ns: 'layout' })}</span>
<span className="px-0.5 system-xs-medium text-text-secondary">{expand ? t('sidebar.collapseSidebar', { ns: 'layout' }) : t('sidebar.expandSidebar', { ns: 'layout' })}</span>
<ShortcutsName keys={TOGGLE_SHORTCUT} textColor="secondary" />
</div>
)

View File

@ -4,9 +4,9 @@ import type { AnnotationItemBasic } from '../type'
import * as React from 'react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Checkbox from '@/app/components/base/checkbox'
import Drawer from '@/app/components/base/drawer-plus'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import AnnotationFull from '@/app/components/billing/annotation-full'
import { useProviderContext } from '@/context/provider-context'
@ -92,11 +92,11 @@ const AddAnnotationModal: FC<Props> = ({
(
<div>
{isAnnotationFull && (
<div className="mb-4 mt-6 px-6">
<div className="mt-6 mb-4 px-6">
<AnnotationFull />
</div>
)}
<div className="system-sm-medium flex h-16 items-center justify-between rounded-bl-xl rounded-br-xl border-t border-divider-subtle bg-background-section-burn px-4 text-text-tertiary">
<div className="flex h-16 items-center justify-between rounded-br-xl rounded-bl-xl border-t border-divider-subtle bg-background-section-burn px-4 system-sm-medium text-text-tertiary">
<div
className="flex items-center space-x-2"
>

View File

@ -4,8 +4,8 @@ import { RiDeleteBinLine } from '@remixicon/react'
import * as React from 'react'
import { useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import { Csv as CSVIcon } from '@/app/components/base/icons/src/public/files'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import { cn } from '@/utils/classnames'
@ -100,7 +100,7 @@ const CSVUploader: FC<Props> = ({
<span className="cursor-pointer text-text-accent" onClick={selectHandle}>{t('batchModal.browse', { ns: 'appAnnotation' })}</span>
</div>
</div>
{dragging && <div ref={dragRef} className="absolute left-0 top-0 h-full w-full" />}
{dragging && <div ref={dragRef} className="absolute top-0 left-0 h-full w-full" />}
</div>
)}
{file && (

View File

@ -5,8 +5,8 @@ import { noop } from 'es-toolkit/function'
import * as React from 'react'
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Modal from '@/app/components/base/modal'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import AnnotationFull from '@/app/components/billing/annotation-full'
import { useProviderContext } from '@/context/provider-context'
@ -89,8 +89,8 @@ const BatchModal: FC<IBatchModalProps> = ({
return (
<Modal isShow={isShow} onClose={noop} className="max-w-[520px]! rounded-xl! px-8 py-6">
<div className="system-xl-medium relative pb-1 text-text-primary">{t('batchModal.title', { ns: 'appAnnotation' })}</div>
<div className="absolute right-4 top-4 cursor-pointer p-2" onClick={onCancel}>
<div className="relative pb-1 system-xl-medium text-text-primary">{t('batchModal.title', { ns: 'appAnnotation' })}</div>
<div className="absolute top-4 right-4 cursor-pointer p-2" onClick={onCancel}>
<RiCloseLine className="h-4 w-4 text-text-tertiary" />
</div>
<CSVUploader
@ -106,7 +106,7 @@ const BatchModal: FC<IBatchModalProps> = ({
)}
<div className="mt-[28px] flex justify-end pt-6">
<Button className="system-sm-medium mr-2 text-text-tertiary" onClick={onCancel}>
<Button className="mr-2 system-sm-medium text-text-tertiary" onClick={onCancel}>
{t('batchModal.cancel', { ns: 'appAnnotation' })}
</Button>
<Button

View File

@ -4,9 +4,9 @@ import { RiDeleteBinLine, RiEditFill, RiEditLine } from '@remixicon/react'
import * as React from 'react'
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import { Robot, User } from '@/app/components/base/icons/src/public/avatar'
import Textarea from '@/app/components/base/textarea'
import { Button } from '@/app/components/base/ui/button'
import { cn } from '@/utils/classnames'
export enum EditItemType {
@ -21,7 +21,7 @@ type Props = {
}
export const EditTitle: FC<{ className?: string, title: string }> = ({ className, title }) => (
<div className={cn(className, 'system-xs-medium flex h-[18px] items-center text-text-tertiary')}>
<div className={cn(className, 'flex h-[18px] items-center system-xs-medium text-text-tertiary')}>
<RiEditFill className="mr-1 h-3.5 w-3.5" />
<div>{title}</div>
<div
@ -75,7 +75,7 @@ const EditItem: FC<Props> = ({
{avatar}
</div>
<div className="grow">
<div className="system-xs-semibold mb-1 text-text-primary">{name}</div>
<div className="mb-1 system-xs-semibold text-text-primary">{name}</div>
<div className="system-sm-regular text-text-primary">{content}</div>
{!isEdit
? (
@ -83,13 +83,13 @@ const EditItem: FC<Props> = ({
{showNewContent && (
<div className="mt-3">
<EditTitle title={editTitle} />
<div className="system-sm-regular mt-1 text-text-primary">{newContent}</div>
<div className="mt-1 system-sm-regular text-text-primary">{newContent}</div>
</div>
)}
<div className="mt-2 flex items-center">
{!readonly && (
<div
className="system-xs-medium flex cursor-pointer items-center space-x-1 text-text-accent"
className="flex cursor-pointer items-center space-x-1 system-xs-medium text-text-accent"
onClick={() => {
setIsEdit(true)
}}
@ -100,7 +100,7 @@ const EditItem: FC<Props> = ({
)}
{showNewContent && (
<div className="system-xs-medium ml-2 flex items-center text-text-tertiary">
<div className="ml-2 flex items-center system-xs-medium text-text-tertiary">
<div className="mr-2">·</div>
<div
className="flex cursor-pointer items-center space-x-1"

View File

@ -16,13 +16,13 @@ import {
import { ChevronRight } from '@/app/components/base/icons/src/vender/line/arrows'
import { FileDownload02, FilePlus02 } from '@/app/components/base/icons/src/vender/line/files'
import CustomPopover from '@/app/components/base/popover'
import { Button } from '@/app/components/base/ui/button'
import { useLocale } from '@/context/i18n'
import { LanguagesSupported } from '@/i18n-config/language'
import { clearAllAnnotations, fetchExportAnnotationList } from '@/service/annotation'
import { clearAllAnnotations, fetchExportAnnotationList } from '@/service/annotation'
import { cn } from '@/utils/classnames'
import { downloadBlob } from '@/utils/download'
import Button from '../../../base/button'
import AddAnnotationModal from '../add-annotation-modal'
import BatchAddModal from '../batch-add-annotation-modal'
import ClearAllAnnotationsConfirmModal from '../clear-all-annotations-confirm-modal'
@ -103,12 +103,12 @@ const HeaderOptions: FC<Props> = ({
}}
>
<FilePlus02 className="h-4 w-4 text-text-tertiary" />
<span className="system-sm-regular grow text-left text-text-secondary">{t('table.header.bulkImport', { ns: 'appAnnotation' })}</span>
<span className="grow text-left system-sm-regular text-text-secondary">{t('table.header.bulkImport', { ns: 'appAnnotation' })}</span>
</button>
<Menu as="div" className="relative h-full w-full">
<MenuButton className="mx-1 flex h-9 w-[calc(100%-8px)] cursor-pointer items-center space-x-2 rounded-lg px-3 py-2 hover:bg-components-panel-on-panel-item-bg-hover disabled:opacity-50">
<FileDownload02 className="h-4 w-4 text-text-tertiary" />
<span className="system-sm-regular grow text-left text-text-secondary">{t('table.header.bulkExport', { ns: 'appAnnotation' })}</span>
<span className="grow text-left system-sm-regular text-text-secondary">{t('table.header.bulkExport', { ns: 'appAnnotation' })}</span>
<ChevronRight className="h-[14px] w-[14px] shrink-0 text-text-tertiary" />
</MenuButton>
<Transition
@ -122,7 +122,7 @@ const HeaderOptions: FC<Props> = ({
>
<MenuItems
className={cn(
'absolute left-1 top-px z-10 min-w-[100px] origin-top-right -translate-x-full rounded-xl border-[0.5px] border-components-panel-on-panel-item-bg bg-components-panel-bg py-1 shadow-xs',
'absolute top-px left-1 z-10 min-w-[100px] origin-top-right -translate-x-full rounded-xl border-[0.5px] border-components-panel-on-panel-item-bg bg-components-panel-bg py-1 shadow-xs',
)}
>
<CSVDownloader
@ -135,11 +135,11 @@ const HeaderOptions: FC<Props> = ({
]}
>
<button type="button" disabled={annotationUnavailable} className="mx-1 flex h-9 w-[calc(100%-8px)] cursor-pointer items-center space-x-2 rounded-lg px-3 py-2 hover:bg-components-panel-on-panel-item-bg-hover disabled:opacity-50">
<span className="system-sm-regular grow text-left text-text-secondary">CSV</span>
<span className="grow text-left system-sm-regular text-text-secondary">CSV</span>
</button>
</CSVDownloader>
<button type="button" disabled={annotationUnavailable} className={cn('mx-1 flex h-9 w-[calc(100%-8px)] cursor-pointer items-center space-x-2 rounded-lg px-3 py-2 hover:bg-components-panel-on-panel-item-bg-hover disabled:opacity-50', 'border-0!')} onClick={JSONLOutput}>
<span className="system-sm-regular grow text-left text-text-secondary">JSONL</span>
<span className="grow text-left system-sm-regular text-text-secondary">JSONL</span>
</button>
</MenuItems>
</Transition>
@ -150,7 +150,7 @@ const HeaderOptions: FC<Props> = ({
className="mx-1 flex h-9 w-[calc(100%-8px)] cursor-pointer items-center space-x-2 rounded-lg px-3 py-2 text-red-600 hover:bg-red-50 disabled:opacity-50"
>
<RiDeleteBinLine className="h-4 w-4" />
<span className="system-sm-regular grow text-left">
<span className="grow text-left system-sm-regular">
{t('table.header.clearAll', { ns: 'appAnnotation' })}
</span>
</button>

View File

@ -6,12 +6,12 @@ import { useDebounce } from 'ahooks'
import { useCallback, useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Avatar } from '@/app/components/base/ui/avatar'
import { Button } from '@/app/components/base/ui/button'
import { useSelector } from '@/context/app-context'
import { SubjectType } from '@/models/access-control'
import { useSearchForWhiteListCandidates } from '@/service/access-control'
import { cn } from '@/utils/classnames'
import useAccessControlStore from '../../../../context/access-control-store'
import Button from '../../base/button'
import Checkbox from '../../base/checkbox'
import Input from '../../base/input'
import Loading from '../../base/loading'
@ -118,7 +118,7 @@ function SelectedGroupsBreadCrumb() {
<span className={cn('system-xs-regular text-text-tertiary', selectedGroupsForBreadcrumb.length > 0 && 'cursor-pointer text-text-accent')} onClick={handleReset}>{t('accessControlDialog.operateGroupAndMember.allMembers', { ns: 'app' })}</span>
{selectedGroupsForBreadcrumb.map((group, index) => {
return (
<div key={index} className="system-xs-regular flex items-center gap-x-0.5 text-text-tertiary">
<div key={index} className="flex items-center gap-x-0.5 system-xs-regular text-text-tertiary">
<span>/</span>
<span className={index === selectedGroupsForBreadcrumb.length - 1 ? '' : 'cursor-pointer text-text-accent'} onClick={() => handleBreadCrumbClick(index)}>{group.name}</span>
</div>
@ -161,7 +161,7 @@ function GroupItem({ group }: GroupItemProps) {
<RiOrganizationChart className="h-[14px] w-[14px] text-components-avatar-shape-fill-stop-0" />
</div>
</div>
<p className="system-sm-medium mr-1 text-text-secondary">{group.name}</p>
<p className="mr-1 system-sm-medium text-text-secondary">{group.name}</p>
<p className="system-xs-regular text-text-tertiary">{group.groupSize}</p>
</div>
<Button
@ -206,7 +206,7 @@ function MemberItem({ member }: MemberItemProps) {
<Avatar size="xxs" avatar={null} name={member.name} />
</div>
</div>
<p className="system-sm-medium mr-1 text-text-secondary">{member.name}</p>
<p className="mr-1 system-sm-medium text-text-secondary">{member.name}</p>
{currentUser.email === member.email && (
<p className="system-xs-regular text-text-tertiary">
(

View File

@ -5,12 +5,12 @@ import { Description as DialogDescription, DialogTitle } from '@headlessui/react
import { RiBuildingLine, RiGlobalLine, RiVerifiedBadgeLine } from '@remixicon/react'
import { useCallback, useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import { useGlobalPublicStore } from '@/context/global-public-context'
import { AccessMode, SubjectType } from '@/models/access-control'
import { useUpdateAccessMode } from '@/service/access-control'
import useAccessControlStore from '../../../../context/access-control-store'
import Button from '../../base/button'
import AccessControlDialog from './access-control-dialog'
import AccessControlItem from './access-control-item'
import SpecificGroupsOrMembers, { WebAppSSONotEnabledTip } from './specific-groups-or-members'
@ -67,9 +67,9 @@ export default function AccessControl(props: AccessControlProps) {
return (
<AccessControlDialog show onClose={onClose}>
<div className="flex flex-col gap-y-3">
<div className="pb-3 pl-6 pr-14 pt-6">
<div className="pt-6 pr-14 pb-3 pl-6">
<DialogTitle className="title-2xl-semi-bold text-text-primary">{t('accessControlDialog.title', { ns: 'app' })}</DialogTitle>
<DialogDescription className="system-xs-regular mt-1 text-text-tertiary">{t('accessControlDialog.description', { ns: 'app' })}</DialogDescription>
<DialogDescription className="mt-1 system-xs-regular text-text-tertiary">{t('accessControlDialog.description', { ns: 'app' })}</DialogDescription>
</div>
<div className="flex flex-col gap-y-1 px-6 pb-3">
<div className="leading-6">

View File

@ -13,12 +13,12 @@ import { useTranslation } from 'react-i18next'
import EmbeddedModal from '@/app/components/app/overview/embedded'
import { useStore as useAppStore } from '@/app/components/app/store'
import { trackEvent } from '@/app/components/base/amplitude'
import Button from '@/app/components/base/button'
import {
PortalToFollowElem,
PortalToFollowElemContent,
PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
import { Button } from '@/app/components/base/ui/button'
import { useGlobalPublicStore } from '@/context/global-public-context'
import { useAsyncWindowOpen } from '@/hooks/use-async-window-open'
import { useFormatTimeFromNow } from '@/hooks/use-format-time-from-now'
@ -224,7 +224,7 @@ const AppPublisher = ({
<PortalToFollowElemTrigger onClick={handleTrigger}>
<Button
variant="primary"
className="py-2 pl-3 pr-2"
className="py-2 pr-2 pl-3"
disabled={disabled}
>
{t('common.publish', { ns: 'workflow' })}

View File

@ -4,12 +4,12 @@ import type { Model, ModelItem } from '@/app/components/header/account-setting/m
import { RiArrowDownSLine } from '@remixicon/react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import {
PortalToFollowElem,
PortalToFollowElemContent,
PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
import { Button } from '@/app/components/base/ui/button'
import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks'
import { useProviderContext } from '@/context/provider-context'
import ModelIcon from '../../header/account-setting/model-provider-page/model-icon'

View File

@ -3,10 +3,10 @@ import type { ModelAndParameter } from '../configuration/debug/types'
import type { AppPublisherProps } from './index'
import type { PublishWorkflowParams } from '@/types/workflow'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Divider from '@/app/components/base/divider'
import { CodeBrowser } from '@/app/components/base/icons/src/vender/line/development'
import Loading from '@/app/components/base/loading'
import { Button } from '@/app/components/base/ui/button'
import {
Tooltip,
TooltipContent,

View File

@ -5,8 +5,8 @@ import * as React from 'react'
import { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Modal from '@/app/components/base/modal'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import Button from '../../base/button'
import Input from '../../base/input'
import Textarea from '../../base/textarea'
@ -67,17 +67,17 @@ const VersionInfoModal: FC<VersionInfoModalProps> = ({
return (
<Modal className="p-0" isShow={isOpen} onClose={onClose}>
<div className="relative w-full p-6 pb-4 pr-14">
<div className="relative w-full p-6 pr-14 pb-4">
<div className="title-2xl-semi-bold text-text-primary first-letter:capitalize">
{versionInfo?.marked_name ? t('versionHistory.editVersionInfo', { ns: 'workflow' }) : t('versionHistory.nameThisVersion', { ns: 'workflow' })}
</div>
<div className="absolute right-5 top-5 flex h-8 w-8 cursor-pointer items-center justify-center p-1.5" onClick={onClose}>
<div className="absolute top-5 right-5 flex h-8 w-8 cursor-pointer items-center justify-center p-1.5" onClick={onClose}>
<RiCloseLine className="h-[18px] w-[18px] text-text-tertiary" />
</div>
</div>
<div className="flex flex-col gap-y-4 px-6 py-3">
<div className="flex flex-col gap-y-1">
<div className="system-sm-semibold flex h-6 items-center text-text-secondary">
<div className="flex h-6 items-center system-sm-semibold text-text-secondary">
{t('versionHistory.editField.title', { ns: 'workflow' })}
</div>
<Input
@ -88,7 +88,7 @@ const VersionInfoModal: FC<VersionInfoModalProps> = ({
/>
</div>
<div className="flex flex-col gap-y-1">
<div className="system-sm-semibold flex h-6 items-center text-text-secondary">
<div className="flex h-6 items-center system-sm-semibold text-text-secondary">
{t('versionHistory.editField.releaseNotes', { ns: 'workflow' })}
</div>
<Textarea

View File

@ -2,7 +2,7 @@
import type { FC } from 'react'
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import { Button } from '@/app/components/base/ui/button'
import WarningMask from '.'
type IFormattingChangedProps = {

View File

@ -2,7 +2,7 @@
import type { FC } from 'react'
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import { Button } from '@/app/components/base/ui/button'
import WarningMask from '.'
type IFormattingChangedProps = {

View File

@ -13,13 +13,13 @@ import * as React from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import { ADD_EXTERNAL_DATA_TOOL } from '@/app/components/app/configuration/config-var'
import Button from '@/app/components/base/button'
import {
Copy,
CopyCheck,
} from '@/app/components/base/icons/src/vender/line/files'
import PromptEditor from '@/app/components/base/prompt-editor'
import { INSERT_VARIABLE_VALUE_BLOCK_COMMAND } from '@/app/components/base/prompt-editor/plugins/variable-block'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import {
Tooltip,
@ -148,14 +148,14 @@ const AdvancedPromptInput: FC<Props> = ({
const [editorHeight, setEditorHeight] = React.useState(isChatMode ? 200 : 508)
const contextMissing = (
<div
className="flex h-11 items-center justify-between rounded-tl-xl rounded-tr-xl pb-1 pl-4 pr-3 pt-2"
className="flex h-11 items-center justify-between rounded-tl-xl rounded-tr-xl pt-2 pr-3 pb-1 pl-4"
style={{
background: 'linear-gradient(180deg, #FEF0C7 0%, rgba(254, 240, 199, 0) 100%)',
}}
>
<div className="flex items-center pr-2">
<RiErrorWarningFill className="mr-1 h-4 w-4 text-[#F79009]" />
<div className="text-[13px] font-medium leading-[18px] text-[#DC6803]">{t('promptMode.contextMissing', { ns: 'appDebug' })}</div>
<div className="text-[13px] leading-[18px] font-medium text-[#DC6803]">{t('promptMode.contextMissing', { ns: 'appDebug' })}</div>
</div>
<Button
size="small"
@ -172,7 +172,7 @@ const AdvancedPromptInput: FC<Props> = ({
{isContextMissing
? contextMissing
: (
<div className={cn(s.boxHeader, 'flex h-11 items-center justify-between rounded-tl-xl rounded-tr-xl bg-background-default pb-1 pl-4 pr-3 pt-2 hover:shadow-xs')}>
<div className={cn(s.boxHeader, 'flex h-11 items-center justify-between rounded-tl-xl rounded-tr-xl bg-background-default pt-2 pr-3 pb-1 pl-4 hover:shadow-xs')}>
{isChatMode
? (
<MessageTypeSelector value={type} onChange={onTypeChange} />
@ -180,13 +180,13 @@ const AdvancedPromptInput: FC<Props> = ({
: (
<div className="flex items-center space-x-1">
<div className="text-sm font-semibold uppercase text-indigo-800">
<div className="text-sm font-semibold text-indigo-800 uppercase">
{t('pageTitle.line1', { ns: 'appDebug' })}
</div>
<Tooltip>
<TooltipTrigger
render={(
<span className="i-ri-question-line ml-1 h-4 w-4 shrink-0 text-text-quaternary" />
<span className="ml-1 i-ri-question-line h-4 w-4 shrink-0 text-text-quaternary" />
)}
/>
<TooltipContent>

View File

@ -3,7 +3,7 @@ import type { FC } from 'react'
import * as React from 'react'
import { useRef } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import { Button } from '@/app/components/base/ui/button'
import VarHighlight from '../../base/var-highlight'
type IConfirmAddVarProps = {
@ -35,7 +35,7 @@ const ConfirmAddVar: FC<IConfirmAddVarProps> = ({
// }, mainContentRef)
return (
<div
className="absolute inset-0 flex items-center justify-center rounded-xl"
className="absolute inset-0 flex items-center justify-center rounded-xl"
style={{
backgroundColor: 'rgba(35, 56, 118, 0.2)',
}}

View File

@ -4,8 +4,8 @@ import type { ConversationHistoriesRole } from '@/models/debug'
import * as React from 'react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Modal from '@/app/components/base/modal'
import { Button } from '@/app/components/base/ui/button'
type Props = {
isShow: boolean
@ -30,7 +30,7 @@ const EditModal: FC<Props> = ({
isShow={isShow}
onClose={onClose}
>
<div className="mt-6 text-sm font-medium leading-[21px] text-text-primary">{t('feature.conversationHistory.editModal.userPrefix', { ns: 'appDebug' })}</div>
<div className="mt-6 text-sm leading-[21px] font-medium text-text-primary">{t('feature.conversationHistory.editModal.userPrefix', { ns: 'appDebug' })}</div>
<input
className="mt-2 box-border h-10 w-full rounded-lg bg-components-input-bg-normal px-3 text-sm leading-10"
value={tempData.user_prefix}
@ -40,7 +40,7 @@ const EditModal: FC<Props> = ({
})}
/>
<div className="mt-6 text-sm font-medium leading-[21px] text-text-primary">{t('feature.conversationHistory.editModal.assistantPrefix', { ns: 'appDebug' })}</div>
<div className="mt-6 text-sm leading-[21px] font-medium text-text-primary">{t('feature.conversationHistory.editModal.assistantPrefix', { ns: 'appDebug' })}</div>
<input
className="mt-2 box-border h-10 w-full rounded-lg bg-components-input-bg-normal px-3 text-sm leading-10"
value={tempData.assistant_prefix}

View File

@ -10,7 +10,7 @@ import * as React from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import AdvancedMessageInput from '@/app/components/app/configuration/config-prompt/advanced-prompt-input'
import Button from '@/app/components/base/button'
import { Button } from '@/app/components/base/ui/button'
import { MAX_PROMPT_MESSAGE_LENGTH } from '@/config'
import ConfigContext from '@/context/debug-configuration'
import { PromptRole } from '@/models/debug'

View File

@ -2,7 +2,7 @@
import type { FC } from 'react'
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import { Button } from '@/app/components/base/ui/button'
type IModalFootProps = {
onConfirm: () => void

View File

@ -3,12 +3,12 @@ import type { FC } from 'react'
import { RiSettings2Line } from '@remixicon/react'
import { memo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import {
PortalToFollowElem,
PortalToFollowElemContent,
PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
import { Button } from '@/app/components/base/ui/button'
import { cn } from '@/utils/classnames'
import ParamConfigContent from './param-config-content'

View File

@ -5,7 +5,7 @@ import { RiSettings2Line } from '@remixicon/react'
import * as React from 'react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import { Button } from '@/app/components/base/ui/button'
import AgentSetting from './agent/agent-setting'
type Props = {

View File

@ -6,9 +6,9 @@ import { useClickAway } from 'ahooks'
import * as React from 'react'
import { useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import { CuteRobot } from '@/app/components/base/icons/src/vender/solid/communication'
import { Unblur } from '@/app/components/base/icons/src/vender/solid/education'
import { Button } from '@/app/components/base/ui/button'
import { Slider } from '@/app/components/base/ui/slider'
import { DEFAULT_AGENT_PROMPT, MAX_ITERATIONS_NUM } from '@/config'
import ItemPanel from './item-panel'
@ -59,7 +59,7 @@ const AgentSetting: FC<Props> = ({
ref={ref}
className="flex h-full w-[640px] flex-col overflow-hidden rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xl"
>
<div className="flex h-14 shrink-0 items-center justify-between border-b border-divider-regular pl-6 pr-5">
<div className="flex h-14 shrink-0 items-center justify-between border-b border-divider-regular pr-5 pl-6">
<div className="flex flex-col text-base font-semibold text-text-primary">
<div className="leading-6">{t('agent.setting.name', { ns: 'appDebug' })}</div>
</div>
@ -74,7 +74,7 @@ const AgentSetting: FC<Props> = ({
</div>
{/* Body */}
<div
className="grow overflow-y-auto border-b p-6 pb-[68px] pt-5"
className="grow overflow-y-auto border-b p-6 pt-5 pb-[68px]"
style={{
borderBottom: 'rgba(0, 0, 0, 0.05)',
}}
@ -88,7 +88,7 @@ const AgentSetting: FC<Props> = ({
name={t('agent.agentMode', { ns: 'appDebug' })}
description={t('agent.agentModeDes', { ns: 'appDebug' })}
>
<div className="text-[13px] font-medium leading-[18px] text-text-primary">{isFunctionCall ? t('agent.agentModeType.functionCall', { ns: 'appDebug' }) : t('agent.agentModeType.ReACT', { ns: 'appDebug' })}</div>
<div className="text-[13px] leading-[18px] font-medium text-text-primary">{isFunctionCall ? t('agent.agentModeType.functionCall', { ns: 'appDebug' }) : t('agent.agentModeType.ReACT', { ns: 'appDebug' })}</div>
</ItemPanel>
<ItemPanel
@ -119,7 +119,7 @@ const AgentSetting: FC<Props> = ({
min={maxIterationsMin}
max={MAX_ITERATIONS_NUM}
step={1}
className="block h-7 w-11 rounded-lg border-0 bg-components-input-bg-normal px-1.5 pl-1 leading-7 text-text-primary placeholder:text-text-tertiary focus:ring-1 focus:ring-inset focus:ring-primary-600"
className="block h-7 w-11 rounded-lg border-0 bg-components-input-bg-normal px-1.5 pl-1 leading-7 text-text-primary placeholder:text-text-tertiary focus:ring-1 focus:ring-primary-600 focus:ring-inset"
value={tempPayload.max_iteration}
onChange={(e) => {
let value = Number.parseInt(e.target.value, 10)
@ -139,12 +139,12 @@ const AgentSetting: FC<Props> = ({
{!isFunctionCall && (
<div className="rounded-xl bg-background-section-burn py-2 shadow-xs">
<div className="flex h-8 items-center px-4 text-sm font-semibold leading-6 text-text-secondary">{t('builtInPromptTitle', { ns: 'tools' })}</div>
<div className="h-[396px] overflow-y-auto whitespace-pre-line px-4 text-sm font-normal leading-5 text-text-secondary">
<div className="flex h-8 items-center px-4 text-sm leading-6 font-semibold text-text-secondary">{t('builtInPromptTitle', { ns: 'tools' })}</div>
<div className="h-[396px] overflow-y-auto px-4 text-sm leading-5 font-normal whitespace-pre-line text-text-secondary">
{isChatModel ? DEFAULT_AGENT_PROMPT.chat : DEFAULT_AGENT_PROMPT.completion}
</div>
<div className="px-4">
<div className="inline-flex h-5 items-center rounded-md bg-components-input-bg-normal px-1 text-xs font-medium leading-[18px] text-text-tertiary">{(isChatModel ? DEFAULT_AGENT_PROMPT.chat : DEFAULT_AGENT_PROMPT.completion).length}</div>
<div className="inline-flex h-5 items-center rounded-md bg-components-input-bg-normal px-1 text-xs leading-[18px] font-medium text-text-tertiary">{(isChatModel ? DEFAULT_AGENT_PROMPT.chat : DEFAULT_AGENT_PROMPT.completion).length}</div>
</div>
</div>
)}

View File

@ -18,11 +18,11 @@ import { useContext } from 'use-context-selector'
import Panel from '@/app/components/app/configuration/base/feature-panel'
import OperationBtn from '@/app/components/app/configuration/base/operation-btn'
import AppIcon from '@/app/components/base/app-icon'
import Button from '@/app/components/base/button'
import { DefaultToolIcon } from '@/app/components/base/icons/src/public/other'
import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
import Switch from '@/app/components/base/switch'
import Tooltip from '@/app/components/base/tooltip'
import { Button } from '@/app/components/base/ui/button'
import Indicator from '@/app/components/header/indicator'
import { CollectionType } from '@/app/components/tools/types'
import { addDefaultValue, toolParametersToFormSchemas } from '@/app/components/tools/utils/to-form-schema'
@ -165,7 +165,7 @@ const AgentTools: FC = () => {
)}
headerRight={(
<div className="flex items-center">
<div className="text-xs font-normal leading-[18px] text-text-tertiary">
<div className="text-xs leading-[18px] font-normal text-text-tertiary">
{tools.filter(item => !!item.enabled).length}
/
{tools.length}
@ -174,7 +174,7 @@ const AgentTools: FC = () => {
</div>
{tools.length < MAX_TOOLS_NUM && !readonly && (
<>
<div className="ml-3 mr-1 h-3.5 w-px bg-divider-regular"></div>
<div className="mr-1 ml-3 h-3.5 w-px bg-divider-regular"></div>
<ToolPicker
trigger={<OperationBtn type="add" />}
isShow={isShowChooseTool}
@ -209,11 +209,11 @@ const AgentTools: FC = () => {
)}
<div
className={cn(
'system-xs-regular ml-1.5 flex w-0 grow items-center truncate',
'ml-1.5 flex w-0 grow items-center truncate system-xs-regular',
(item.isDeleted || item.notAuthor || !item.enabled) ? 'opacity-50' : '',
)}
>
<span className="system-xs-medium pr-1.5 text-text-secondary">{getProviderShowName(item)}</span>
<span className="pr-1.5 system-xs-medium text-text-secondary">{getProviderShowName(item)}</span>
<span className="text-text-tertiary">{item.tool_label}</span>
{!item.isDeleted && !readonly && (
<Tooltip
@ -268,7 +268,7 @@ const AgentTools: FC = () => {
needsDelay={false}
>
<div
className="cursor-pointer rounded-md p-1 hover:bg-black/5"
className="cursor-pointer rounded-md p-1 hover:bg-black/5"
onClick={() => {
setCurrentTool(item)
setIsShowSettingTool(true)

View File

@ -10,10 +10,10 @@ import * as React from 'react'
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import ActionButton from '@/app/components/base/action-button'
import Button from '@/app/components/base/button'
import Drawer from '@/app/components/base/drawer'
import Loading from '@/app/components/base/loading'
import TabSlider from '@/app/components/base/tab-slider-plain'
import { Button } from '@/app/components/base/ui/button'
import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form'
import Icon from '@/app/components/plugins/card/base/card-icon'
import Description from '@/app/components/plugins/card/base/description'
@ -140,7 +140,7 @@ const SettingBuiltInTool: FC<Props> = ({
)}
</div>
{item.human_description && (
<div className="system-xs-regular mt-0.5 text-text-tertiary">
<div className="mt-0.5 system-xs-regular text-text-tertiary">
{item.human_description?.[language]}
</div>
)}
@ -171,7 +171,7 @@ const SettingBuiltInTool: FC<Props> = ({
footer={null}
mask={false}
positionCenter={false}
panelClassName={cn('mb-2 mr-2 mt-[64px] w-[420px]! max-w-[420px]! justify-start rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg! p-0! shadow-xl')}
panelClassName={cn('mt-[64px] mr-2 mb-2 w-[420px]! max-w-[420px]! justify-start rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg! p-0! shadow-xl')}
>
<>
{isLoading && <Loading type="app" />}
@ -179,14 +179,14 @@ const SettingBuiltInTool: FC<Props> = ({
<>
{/* header */}
<div className="relative border-b border-divider-subtle p-4 pb-3">
<div className="absolute right-3 top-3">
<div className="absolute top-3 right-3">
<ActionButton onClick={onHide}>
<RiCloseLine className="h-4 w-4" />
</ActionButton>
</div>
{showBackButton && (
<div
className="system-xs-semibold-uppercase mb-2 flex cursor-pointer items-center gap-1 text-text-accent-secondary"
className="mb-2 flex cursor-pointer items-center gap-1 system-xs-semibold-uppercase text-text-accent-secondary"
onClick={onHide}
>
<RiArrowLeftLine className="h-4 w-4" />
@ -201,9 +201,9 @@ const SettingBuiltInTool: FC<Props> = ({
packageName={collection.name.split('/').pop() || ''}
/>
</div>
<div className="system-md-semibold mt-1 text-text-primary">{currTool?.label[language]}</div>
<div className="mt-1 system-md-semibold text-text-primary">{currTool?.label[language]}</div>
{!!currTool?.description[language] && (
<Description className="mb-2 mt-3 h-auto" text={currTool.description[language]} descriptionLineRows={2}></Description>
<Description className="mt-3 mb-2 h-auto" text={currTool.description[language]} descriptionLineRows={2}></Description>
)}
{
collection.allow_delete && collection.type === CollectionType.builtIn && (
@ -240,13 +240,13 @@ const SettingBuiltInTool: FC<Props> = ({
/>
)
: (
<div className="system-sm-semibold-uppercase p-4 pb-1 text-text-primary">{t('setBuiltInTools.parameters', { ns: 'tools' })}</div>
<div className="p-4 pb-1 system-sm-semibold-uppercase text-text-primary">{t('setBuiltInTools.parameters', { ns: 'tools' })}</div>
)}
<div className="h-0 grow overflow-y-auto px-4">
{isInfoActive ? infoUI : settingUI}
{!readonly && !isInfoActive && (
<div className="flex shrink-0 justify-end space-x-2 rounded-b-[10px] bg-components-panel-bg py-2">
<Button className="flex h-8 items-center px-3! text-[13px]! font-medium " onClick={onHide}>{t('operation.cancel', { ns: 'common' })}</Button>
<Button className="flex h-8 items-center px-3! text-[13px]! font-medium" onClick={onHide}>{t('operation.cancel', { ns: 'common' })}</Button>
<Button className="flex h-8 items-center px-3! text-[13px]! font-medium" variant="primary" disabled={!isValid} onClick={() => onSave?.(tempSetting)}>{t('operation.save', { ns: 'common' })}</Button>
</div>
)}

View File

@ -5,7 +5,7 @@ import {
} from '@remixicon/react'
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import { Button } from '@/app/components/base/ui/button'
type IAutomaticBtnProps = {
onClick: () => void

View File

@ -19,11 +19,11 @@ import { useBoolean, useSessionStorageState } from 'ahooks'
import * as React from 'react'
import { useCallback, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Confirm from '@/app/components/base/confirm'
import { Generator } from '@/app/components/base/icons/src/vender/other'
import Loading from '@/app/components/base/loading'
import Modal from '@/app/components/base/modal'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
@ -62,7 +62,7 @@ const TryLabel: FC<{
}> = ({ Icon, text, onClick }) => {
return (
<div
className="mr-1 mt-2 flex h-7 shrink-0 cursor-pointer items-center rounded-lg bg-components-button-secondary-bg px-2"
className="mt-2 mr-1 flex h-7 shrink-0 cursor-pointer items-center rounded-lg bg-components-button-secondary-bg px-2"
onClick={onClick}
>
<Icon className="h-4 w-4 text-text-tertiary"></Icon>
@ -283,7 +283,7 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
<div className="flex h-[680px] flex-wrap">
<div className="h-full w-[570px] shrink-0 overflow-y-auto border-r border-divider-regular p-6">
<div className="mb-5">
<div className={`text-lg font-bold leading-[28px] ${s.textGradient}`}>{t('generate.title', { ns: 'appDebug' })}</div>
<div className={`text-lg leading-[28px] font-bold ${s.textGradient}`}>{t('generate.title', { ns: 'appDebug' })}</div>
<div className="mt-1 text-[13px] font-normal text-text-tertiary">{t('generate.description', { ns: 'appDebug' })}</div>
</div>
<div>
@ -301,7 +301,7 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
{isBasicMode && (
<div className="mt-4">
<div className="flex items-center">
<div className="mr-3 shrink-0 text-xs font-semibold uppercase leading-[18px] text-text-tertiary">{t('generate.tryIt', { ns: 'appDebug' })}</div>
<div className="mr-3 shrink-0 text-xs leading-[18px] font-semibold text-text-tertiary uppercase">{t('generate.tryIt', { ns: 'appDebug' })}</div>
<div
className="h-px grow"
style={{
@ -326,7 +326,7 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
{/* inputs */}
<div className="mt-4">
<div>
<div className="system-sm-semibold-uppercase mb-1.5 text-text-secondary">{t('generate.instruction', { ns: 'appDebug' })}</div>
<div className="mb-1.5 system-sm-semibold-uppercase text-text-secondary">{t('generate.instruction', { ns: 'appDebug' })}</div>
{isBasicMode
? (
<InstructionEditorInBasic

View File

@ -5,7 +5,7 @@ import { RiClipboardLine } from '@remixicon/react'
import copy from 'copy-to-clipboard'
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import CodeEditor from '@/app/components/workflow/nodes/llm/components/json-schema-config-modal/code-editor'
import PromptRes from './prompt-res'
@ -42,7 +42,7 @@ const Result: FC<Props> = ({
<div className="flex h-full flex-col">
<div className="mb-3 flex shrink-0 items-center justify-between">
<div>
<div className="shrink-0 text-base font-semibold leading-[160%] text-text-secondary">{t('generate.resTitle', { ns: 'appDebug' })}</div>
<div className="shrink-0 text-base leading-[160%] font-semibold text-text-secondary">{t('generate.resTitle', { ns: 'appDebug' })}</div>
<VersionSelector
versionLen={versions.length}
value={currentVersionIndex}

View File

@ -10,11 +10,11 @@ import {
import * as React from 'react'
import { useCallback, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Confirm from '@/app/components/base/confirm'
import { Generator } from '@/app/components/base/icons/src/vender/other'
import Loading from '@/app/components/base/loading'
import Modal from '@/app/components/base/modal'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
@ -202,7 +202,7 @@ export const GetCodeGeneratorResModal: FC<IGetCodeGeneratorResProps> = (
<div className="relative flex h-[680px] flex-wrap">
<div className="h-full w-[570px] shrink-0 overflow-y-auto border-r border-divider-regular p-6">
<div className="mb-5">
<div className={`text-lg font-bold leading-[28px] ${s.textGradient}`}>{t('codegen.title', { ns: 'appDebug' })}</div>
<div className={`text-lg leading-[28px] font-bold ${s.textGradient}`}>{t('codegen.title', { ns: 'appDebug' })}</div>
<div className="mt-1 text-[13px] font-normal text-text-tertiary">{t('codegen.description', { ns: 'appDebug' })}</div>
</div>
<div className="mb-4">
@ -219,7 +219,7 @@ export const GetCodeGeneratorResModal: FC<IGetCodeGeneratorResProps> = (
</div>
<div>
<div className="text-[0px]">
<div className="mb-1.5 text-text-secondary system-sm-semibold-uppercase">{t('codegen.instruction', { ns: 'appDebug' })}</div>
<div className="mb-1.5 system-sm-semibold-uppercase text-text-secondary">{t('codegen.instruction', { ns: 'appDebug' })}</div>
<InstructionEditor
editorKey={editorKey}
value={instruction}

View File

@ -10,7 +10,6 @@ import EditHistoryModal from '@/app/components/app/configuration/config-prompt/c
import AgentSettingButton from '@/app/components/app/configuration/config/agent-setting-button'
import SelectDataSet from '@/app/components/app/configuration/dataset-config/select-dataset'
import Debug from '@/app/components/app/configuration/debug'
import Button from '@/app/components/base/button'
import Divider from '@/app/components/base/divider'
import Drawer from '@/app/components/base/drawer'
import { FeaturesProvider } from '@/app/components/base/features'
@ -25,6 +24,7 @@ import {
AlertDialogDescription,
AlertDialogTitle,
} from '@/app/components/base/ui/alert-dialog'
import { Button } from '@/app/components/base/ui/button'
import ModelParameterModal from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal'
import PluginDependency from '@/app/components/workflow/plugin-dependency'
import ConfigContext from '@/context/debug-configuration'

View File

@ -2,7 +2,7 @@
import type { FC } from 'react'
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import { Button } from '@/app/components/base/ui/button'
import s from './style.module.css'
type IContrlBtnGroupProps = {
@ -14,7 +14,7 @@ const ContrlBtnGroup: FC<IContrlBtnGroupProps> = ({ onSave, onReset }) => {
const { t } = useTranslation()
return (
<div className="fixed bottom-0 left-[224px] h-[64px] w-[519px]">
<div className={`${s.ctrlBtn} flex h-full items-center gap-2 bg-white pl-4`}>
<div className={`${s.ctrlBtn} flex h-full items-center gap-2 bg-white pl-4`}>
<Button variant="primary" onClick={onSave} data-testid="apply-btn">{t('operation.applyConfig', { ns: 'appDebug' })}</Button>
<Button onClick={onReset} data-testid="reset-btn">{t('operation.resetConfig', { ns: 'appDebug' })}</Button>
</div>

View File

@ -5,8 +5,8 @@ import { RiEqualizer2Line } from '@remixicon/react'
import { memo, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import Button from '@/app/components/base/button'
import Modal from '@/app/components/base/modal'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import { useCurrentProviderAndModel, useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks'

View File

@ -7,9 +7,9 @@ import { useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import AppIcon from '@/app/components/base/app-icon'
import Badge from '@/app/components/base/badge'
import Button from '@/app/components/base/button'
import Loading from '@/app/components/base/loading'
import Modal from '@/app/components/base/modal'
import { Button } from '@/app/components/base/ui/button'
import { ModelFeatureEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import FeatureIcon from '@/app/components/header/account-setting/model-provider-page/model-selector/feature-icon'
import { useKnowledge } from '@/hooks/use-knowledge'
@ -134,7 +134,7 @@ const SelectDataSet: FC<ISelectDataSetProps> = ({
</div>
<div className={cn('max-w-[200px] truncate text-[13px] font-medium text-text-secondary', !item.embedding_available && 'max-w-[120px]! opacity-30')}>{item.name}</div>
{!item.embedding_available && (
<span className="ml-1 shrink-0 rounded-md border border-divider-deep px-1 text-xs font-normal leading-[18px] text-text-tertiary">{t('unavailable', { ns: 'dataset' })}</span>
<span className="ml-1 shrink-0 rounded-md border border-divider-deep px-1 text-xs leading-[18px] font-normal text-text-tertiary">{t('unavailable', { ns: 'dataset' })}</span>
)}
</div>
{item.is_multimodal && (

View File

@ -6,9 +6,9 @@ import { RiCloseLine } from '@remixicon/react'
import { isEqual } from 'es-toolkit/predicate'
import { useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
import Textarea from '@/app/components/base/textarea'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import { isReRankModelSelected } from '@/app/components/datasets/common/check-rerank-model'
import { IndexingType } from '@/app/components/datasets/create/step-two'
@ -192,7 +192,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
}}
ref={ref}
>
<div className="flex h-14 shrink-0 items-center justify-between border-b border-divider-regular pl-6 pr-5">
<div className="flex h-14 shrink-0 items-center justify-between border-b border-divider-regular pr-5 pl-6">
<div className="flex flex-col text-base font-semibold text-text-primary">
<div className="leading-6">{t('title', { ns: 'datasetSettings' })}</div>
</div>
@ -206,10 +206,10 @@ const SettingsModal: FC<SettingsModalProps> = ({
</div>
</div>
{/* Body */}
<div className="overflow-y-auto border-b border-divider-regular p-6 pb-[68px] pt-5">
<div className="overflow-y-auto border-b border-divider-regular p-6 pt-5 pb-[68px]">
<div className={cn(rowClass, 'items-center')}>
<div className={labelClass}>
<div className="text-text-secondary system-sm-semibold">{t('form.name', { ns: 'datasetSettings' })}</div>
<div className="system-sm-semibold text-text-secondary">{t('form.name', { ns: 'datasetSettings' })}</div>
</div>
<Input
value={localeCurrentDataset.name}
@ -220,7 +220,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
</div>
<div className={cn(rowClass)}>
<div className={labelClass}>
<div className="text-text-secondary system-sm-semibold">{t('form.desc', { ns: 'datasetSettings' })}</div>
<div className="system-sm-semibold text-text-secondary">{t('form.desc', { ns: 'datasetSettings' })}</div>
</div>
<div className="w-full">
<Textarea
@ -233,7 +233,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
</div>
<div className={rowClass}>
<div className={labelClass}>
<div className="text-text-secondary system-sm-semibold">{t('form.permissions', { ns: 'datasetSettings' })}</div>
<div className="system-sm-semibold text-text-secondary">{t('form.permissions', { ns: 'datasetSettings' })}</div>
</div>
<div className="w-full">
<PermissionSelector
@ -249,7 +249,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
{!!(currentDataset && currentDataset.indexing_technique) && (
<div className={cn(rowClass)}>
<div className={labelClass}>
<div className="text-text-secondary system-sm-semibold">{t('form.indexMethod', { ns: 'datasetSettings' })}</div>
<div className="system-sm-semibold text-text-secondary">{t('form.indexMethod', { ns: 'datasetSettings' })}</div>
</div>
<div className="grow">
<IndexMethod
@ -266,7 +266,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
{indexMethod === IndexingType.QUALIFIED && (
<div className={cn(rowClass)}>
<div className={labelClass}>
<div className="text-text-secondary system-sm-semibold">{t('form.embeddingModel', { ns: 'datasetSettings' })}</div>
<div className="system-sm-semibold text-text-secondary">{t('form.embeddingModel', { ns: 'datasetSettings' })}</div>
</div>
<div className="w-full">
<div className="h-8 w-full rounded-lg bg-components-input-bg-normal opacity-60">

View File

@ -25,10 +25,10 @@ import { useStore as useAppStore } from '@/app/components/app/store'
import TextGeneration from '@/app/components/app/text-generate/item'
import ActionButton, { ActionButtonState } from '@/app/components/base/action-button'
import AgentLogModal from '@/app/components/base/agent-log-modal'
import Button from '@/app/components/base/button'
import { useFeatures, useFeaturesStore } from '@/app/components/base/features/hooks'
import { RefreshCcw01 } from '@/app/components/base/icons/src/vender/line/arrows'
import PromptLogModal from '@/app/components/base/prompt-log-modal'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import {
Tooltip,
@ -394,8 +394,8 @@ const Debug: FC<IDebug> = ({
return (
<>
<div className="shrink-0">
<div className="flex items-center justify-between px-4 pb-2 pt-3">
<div className="text-text-primary system-xl-semibold">{t('inputs.title', { ns: 'appDebug' })}</div>
<div className="flex items-center justify-between px-4 pt-3 pb-2">
<div className="system-xl-semibold text-text-primary">{t('inputs.title', { ns: 'appDebug' })}</div>
<div className="flex items-center">
{
debugWithMultipleModel
@ -432,14 +432,14 @@ const Debug: FC<IDebug> = ({
{
varList.length > 0 && (
<div className="relative ml-1 mr-2">
<div className="relative mr-2 ml-1">
<Tooltip>
<TooltipTrigger render={<ActionButton state={expanded ? ActionButtonState.Active : undefined} onClick={() => !readonly && setExpanded(!expanded)}><RiEqualizer2Line className="h-4 w-4" /></ActionButton>} />
<TooltipContent>
{t('panel.userInputField', { ns: 'workflow' })}
</TooltipContent>
</Tooltip>
{expanded && <div className="absolute bottom-[-14px] right-[5px] z-10 h-3 w-3 rotate-45 border-l-[0.5px] border-t-[0.5px] border-components-panel-border-subtle bg-components-panel-on-panel-item-bg" />}
{expanded && <div className="absolute right-[5px] bottom-[-14px] z-10 h-3 w-3 rotate-45 border-t-[0.5px] border-l-[0.5px] border-components-panel-border-subtle bg-components-panel-on-panel-item-bg" />}
</div>
)
}
@ -517,8 +517,8 @@ const Debug: FC<IDebug> = ({
</div>
</div>
<div className="flex flex-col gap-1">
<div className="text-text-secondary system-md-semibold">{t('noModelSelected', { ns: 'appDebug' })}</div>
<div className="text-text-tertiary system-xs-regular">{t('noModelSelectedTip', { ns: 'appDebug' })}</div>
<div className="system-md-semibold text-text-secondary">{t('noModelSelected', { ns: 'appDebug' })}</div>
<div className="system-xs-regular text-text-tertiary">{t('noModelSelectedTip', { ns: 'appDebug' })}</div>
</div>
</div>
</div>
@ -557,7 +557,7 @@ const Debug: FC<IDebug> = ({
{!completionRes && !isResponding && (
<div className="flex grow flex-col items-center justify-center gap-2">
<RiSparklingFill className="h-12 w-12 text-text-empty-state-icon" />
<div className="text-text-quaternary system-sm-regular">{t('noResult', { ns: 'appDebug' })}</div>
<div className="system-sm-regular text-text-quaternary">{t('noResult', { ns: 'appDebug' })}</div>
</div>
)}
</>

View File

@ -12,13 +12,13 @@ import { useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import { useStore as useAppStore } from '@/app/components/app/store'
import Button from '@/app/components/base/button'
import FeatureBar from '@/app/components/base/features/new-feature-panel/feature-bar'
import TextGenerationImageUploader from '@/app/components/base/image-uploader/text-generation-image-uploader'
import Input from '@/app/components/base/input'
import Select from '@/app/components/base/select'
import Textarea from '@/app/components/base/textarea'
import Tooltip from '@/app/components/base/tooltip'
import { Button } from '@/app/components/base/ui/button'
import BoolInput from '@/app/components/workflow/nodes/_base/components/before-run-form/bool-input'
import ConfigContext from '@/context/debug-configuration'
import { AppModeEnum, ModelModeType } from '@/types/app'
@ -117,11 +117,11 @@ const PromptValuePanel: FC<IPromptValuePanelProps> = ({
{!userInputFieldCollapse && <RiArrowDownSLine className="h-4 w-4 text-text-secondary" />}
</div>
{!userInputFieldCollapse && (
<div className="system-xs-regular mt-1 text-text-tertiary">{t('inputs.completionVarTip', { ns: 'appDebug' })}</div>
<div className="mt-1 system-xs-regular text-text-tertiary">{t('inputs.completionVarTip', { ns: 'appDebug' })}</div>
)}
</div>
{!userInputFieldCollapse && promptVariables.length > 0 && (
<div className="px-4 pb-4 pt-3">
<div className="px-4 pt-3 pb-4">
{promptVariables.map(({ key, name, type, options, max_length, required }, index) => (
<div
key={key}
@ -129,7 +129,7 @@ const PromptValuePanel: FC<IPromptValuePanelProps> = ({
>
<div>
{type !== 'checkbox' && (
<div className="system-sm-semibold mb-1 flex h-6 items-center gap-1 text-text-secondary">
<div className="mb-1 flex h-6 items-center gap-1 system-sm-semibold text-text-secondary">
<div className="truncate">{name || key}</div>
{!required && <span className="system-xs-regular text-text-tertiary">{t('panel.optional', { ns: 'workflow' })}</span>}
</div>

View File

@ -6,10 +6,10 @@ import { noop } from 'es-toolkit/function'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import AppIcon from '@/app/components/base/app-icon'
import Button from '@/app/components/base/button'
import EmojiPicker from '@/app/components/base/emoji-picker'
import FormGeneration from '@/app/components/base/features/new-feature-panel/moderation/form-generation'
import { BookOpen01 } from '@/app/components/base/icons/src/vender/line/education'
import { Button } from '@/app/components/base/ui/button'
import { Dialog, DialogContent } from '@/app/components/base/ui/dialog'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/app/components/base/ui/select'
import { toast } from '@/app/components/base/ui/toast'
@ -116,7 +116,7 @@ const ExternalDataToolModal: FC<ExternalDataToolModalProps> = ({
{`${action} ${t('variableConfig.apiBasedVar', { ns: 'appDebug' })}`}
</div>
<div className="py-2">
<div className="text-sm font-medium leading-9 text-text-primary">
<div className="text-sm leading-9 font-medium text-text-primary">
{t('apiBasedExtension.type', { ns: 'common' })}
</div>
<Select
@ -136,7 +136,7 @@ const ExternalDataToolModal: FC<ExternalDataToolModalProps> = ({
</Select>
</div>
<div className="py-2">
<div className="text-sm font-medium leading-9 text-text-primary">
<div className="text-sm leading-9 font-medium text-text-primary">
{t('feature.tools.modal.name.title', { ns: 'appDebug' })}
</div>
<div className="flex items-center">
@ -156,7 +156,7 @@ const ExternalDataToolModal: FC<ExternalDataToolModalProps> = ({
</div>
</div>
<div className="py-2">
<div className="text-sm font-medium leading-9 text-text-primary">
<div className="text-sm leading-9 font-medium text-text-primary">
{t('feature.tools.modal.variableName.title', { ns: 'appDebug' })}
</div>
<input

View File

@ -6,7 +6,7 @@ import { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import { useContextSelector } from 'use-context-selector'
import AppIcon from '@/app/components/base/app-icon'
import Button from '@/app/components/base/button'
import { Button } from '@/app/components/base/ui/button'
import AppListContext from '@/context/app-list-context'
import { useGlobalPublicStore } from '@/context/global-public-context'
import { cn } from '@/utils/classnames'
@ -34,7 +34,7 @@ const AppCard = ({
}
}, [setShowTryAppPanel, app.category])
return (
<div className={cn('group relative flex h-[132px] cursor-pointer flex-col overflow-hidden rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg p-4 shadow-xs hover:shadow-lg')}>
<div className={cn('group relative flex h-[132px] cursor-pointer flex-col overflow-hidden rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg p-4 shadow-xs hover:shadow-lg')}>
<div className="flex shrink-0 grow-0 items-center gap-3 pb-2">
<div className="relative shrink-0">
<AppIcon
@ -57,13 +57,13 @@ const AppCard = ({
<AppTypeLabel className="system-2xs-medium-uppercase text-text-tertiary" type={app.app.mode} />
</div>
</div>
<div className="system-xs-regular py-1 text-text-tertiary">
<div className="py-1 system-xs-regular text-text-tertiary">
<div className="line-clamp-3">
{app.description}
</div>
</div>
{(canCreate || isTrialApp) && (
<div className={cn('absolute bottom-0 left-0 right-0 hidden bg-linear-to-t from-components-panel-gradient-2 from-[60.27%] to-transparent p-4 pt-8 group-hover:flex')}>
<div className={cn('absolute right-0 bottom-0 left-0 hidden bg-linear-to-t from-components-panel-gradient-2 from-[60.27%] to-transparent p-4 pt-8 group-hover:flex')}>
<div className={cn('grid h-8 w-full grid-cols-1 items-center space-x-2', canCreate && 'grid-cols-2')}>
{canCreate && (
<Button variant="primary" onClick={() => onCreate()}>

View File

@ -8,12 +8,12 @@ import { useCallback, useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { trackEvent } from '@/app/components/base/amplitude'
import AppIcon from '@/app/components/base/app-icon'
import Button from '@/app/components/base/button'
import Divider from '@/app/components/base/divider'
import FullScreenModal from '@/app/components/base/fullscreen-modal'
import { BubbleTextMod, ChatBot, ListSparkle, Logic } from '@/app/components/base/icons/src/vender/solid/communication'
import Input from '@/app/components/base/input'
import Textarea from '@/app/components/base/textarea'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import AppsFull from '@/app/components/billing/apps-full-in-dialog'
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
@ -106,15 +106,15 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }:
})
return (
<>
<div className="flex h-full justify-center overflow-y-auto overflow-x-hidden">
<div className="flex h-full justify-center overflow-x-hidden overflow-y-auto">
<div className="flex flex-1 shrink-0 justify-end">
<div className="px-10">
<div className="h-6 w-full 2xl:h-[139px]" />
<div className="pb-6 pt-1">
<span className="text-text-primary title-2xl-semi-bold">{t('newApp.startFromBlank', { ns: 'app' })}</span>
<div className="pt-1 pb-6">
<span className="title-2xl-semi-bold text-text-primary">{t('newApp.startFromBlank', { ns: 'app' })}</span>
</div>
<div className="mb-2 leading-6">
<span className="text-text-secondary system-sm-semibold">{t('newApp.chooseAppType', { ns: 'app' })}</span>
<span className="system-sm-semibold text-text-secondary">{t('newApp.chooseAppType', { ns: 'app' })}</span>
</div>
<div className="flex w-[660px] flex-col gap-4">
<div>
@ -154,7 +154,7 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }:
className="flex cursor-pointer items-center border-0 bg-transparent p-0"
onClick={() => setIsAppTypeExpanded(!isAppTypeExpanded)}
>
<span className="text-text-tertiary system-2xs-medium-uppercase">{t('newApp.forBeginners', { ns: 'app' })}</span>
<span className="system-2xs-medium-uppercase text-text-tertiary">{t('newApp.forBeginners', { ns: 'app' })}</span>
<RiArrowRightSLine className={`ml-1 h-4 w-4 text-text-tertiary transition-transform ${isAppTypeExpanded ? 'rotate-90' : ''}`} />
</button>
</div>
@ -206,7 +206,7 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }:
<div className="flex items-center space-x-3">
<div className="flex-1">
<div className="mb-1 flex h-6 items-center">
<label className="text-text-secondary system-sm-semibold">{t('newApp.captionName', { ns: 'app' })}</label>
<label className="system-sm-semibold text-text-secondary">{t('newApp.captionName', { ns: 'app' })}</label>
</div>
<Input
value={name}
@ -237,8 +237,8 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }:
</div>
<div>
<div className="mb-1 flex h-6 items-center">
<label className="text-text-secondary system-sm-semibold">{t('newApp.captionDescription', { ns: 'app' })}</label>
<span className="ml-1 text-text-tertiary system-xs-regular">
<label className="system-sm-semibold text-text-secondary">{t('newApp.captionDescription', { ns: 'app' })}</label>
<span className="ml-1 system-xs-regular text-text-tertiary">
(
{t('newApp.optional', { ns: 'app' })}
)
@ -253,8 +253,8 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }:
</div>
</div>
{isAppsFull && <AppsFull className="mt-4" loc="app-create" />}
<div className="flex items-center justify-between pb-10 pt-5">
<div className="flex cursor-pointer items-center gap-1 text-text-tertiary system-xs-regular" onClick={onCreateFromTemplate}>
<div className="flex items-center justify-between pt-5 pb-10">
<div className="flex cursor-pointer items-center gap-1 system-xs-regular text-text-tertiary" onClick={onCreateFromTemplate}>
<span>{t('newApp.noIdeaTip', { ns: 'app' })}</span>
<div className="p-px">
<RiArrowRightLine className="h-3.5 w-3.5" />
@ -271,11 +271,11 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }:
</div>
</div>
<div className="relative flex h-full flex-1 shrink justify-start overflow-hidden">
<div className="absolute left-0 right-0 top-0 h-6 border-b border-b-divider-subtle 2xl:h-[139px]"></div>
<div className="absolute top-0 right-0 left-0 h-6 border-b border-b-divider-subtle 2xl:h-[139px]"></div>
<div className="max-w-[760px] border-x border-x-divider-subtle">
<div className="h-6 2xl:h-[139px]" />
<AppPreview mode={appMode} />
<div className="absolute left-0 right-0 border-b border-b-divider-subtle"></div>
<div className="absolute right-0 left-0 border-b border-b-divider-subtle"></div>
<div className="flex h-[448px] w-[664px] items-center justify-center" style={{ background: 'repeating-linear-gradient(135deg, transparent, transparent 2px, rgba(16,24,40,0.04) 4px,transparent 3px, transparent 6px)' }}>
<AppScreenShot show={appMode === AppModeEnum.CHAT} mode={AppModeEnum.CHAT} />
<AppScreenShot show={appMode === AppModeEnum.ADVANCED_CHAT} mode={AppModeEnum.ADVANCED_CHAT} />
@ -283,7 +283,7 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }:
<AppScreenShot show={appMode === AppModeEnum.COMPLETION} mode={AppModeEnum.COMPLETION} />
<AppScreenShot show={appMode === AppModeEnum.WORKFLOW} mode={AppModeEnum.WORKFLOW} />
</div>
<div className="absolute left-0 right-0 border-b border-b-divider-subtle"></div>
<div className="absolute right-0 left-0 border-b border-b-divider-subtle"></div>
</div>
</div>
</div>
@ -322,14 +322,14 @@ function AppTypeCard({ icon, title, description, active, onClick }: AppTypeCardP
cn(`relative box-content h-[84px] w-[191px] cursor-pointer rounded-xl
border-[0.5px] border-components-option-card-option-border
bg-components-panel-on-panel-item-bg p-3 shadow-xs hover:shadow-md`, active
? 'shadow-md outline-solid outline-[1.5px] outline-components-option-card-option-selected-border'
? 'shadow-md outline-[1.5px] outline-components-option-card-option-selected-border outline-solid'
: '')
}
onClick={onClick}
>
{icon}
<div className="mb-0.5 mt-2 text-text-secondary system-sm-semibold">{title}</div>
<div className="line-clamp-2 text-text-tertiary system-xs-regular" title={description}>{description}</div>
<div className="mt-2 mb-0.5 system-sm-semibold text-text-secondary">{title}</div>
<div className="line-clamp-2 system-xs-regular text-text-tertiary" title={description}>{description}</div>
</div>
)
}
@ -361,8 +361,8 @@ function AppPreview({ mode }: { mode: AppModeEnum }) {
const previewInfo = modeToPreviewInfoMap[mode]
return (
<div className="px-8 py-4">
<h4 className="text-text-secondary system-sm-semibold-uppercase">{previewInfo.title}</h4>
<div className="mt-1 min-h-8 max-w-96 text-text-tertiary system-xs-regular">
<h4 className="system-sm-semibold-uppercase text-text-secondary">{previewInfo.title}</h4>
<div className="mt-1 min-h-8 max-w-96 system-xs-regular text-text-tertiary">
<span>{previewInfo.description}</span>
</div>
</div>

View File

@ -1,6 +1,6 @@
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Modal from '@/app/components/base/modal'
import { Button } from '@/app/components/base/ui/button'
type DSLConfirmModalProps = {
versions?: {
@ -27,7 +27,7 @@ const DSLConfirmModal = ({
>
<div className="flex flex-col items-start gap-2 self-stretch pb-4">
<div className="title-2xl-semi-bold text-text-primary">{t('newApp.appCreateDSLErrorTitle', { ns: 'app' })}</div>
<div className="system-md-regular flex grow flex-col text-text-secondary">
<div className="flex grow flex-col system-md-regular text-text-secondary">
<div>{t('newApp.appCreateDSLErrorPart1', { ns: 'app' })}</div>
<div>{t('newApp.appCreateDSLErrorPart2', { ns: 'app' })}</div>
<br />

View File

@ -7,9 +7,9 @@ import { noop } from 'es-toolkit/function'
import { useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { trackEvent } from '@/app/components/base/amplitude'
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
import Modal from '@/app/components/base/modal'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import AppsFull from '@/app/components/billing/apps-full-in-dialog'
import { usePluginDependencies } from '@/app/components/workflow/plugin-dependency/hooks'
@ -228,7 +228,7 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS
isShow={show}
onClose={noop}
>
<div className="flex items-center justify-between pb-3 pl-6 pr-5 pt-6 text-text-primary title-2xl-semi-bold">
<div className="flex items-center justify-between pt-6 pr-5 pb-3 pl-6 title-2xl-semi-bold text-text-primary">
{t('importFromDSL', { ns: 'app' })}
<div
className="flex h-8 w-8 cursor-pointer items-center"
@ -237,7 +237,7 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS
<RiCloseLine className="h-5 w-5 text-text-tertiary" />
</div>
</div>
<div className="flex h-9 items-center space-x-6 border-b border-divider-subtle px-6 text-text-tertiary system-md-semibold">
<div className="flex h-9 items-center space-x-6 border-b border-divider-subtle px-6 system-md-semibold text-text-tertiary">
{
tabs.map(tab => (
<div
@ -271,7 +271,7 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS
{
currentTab === CreateFromDSLModalTab.FROM_URL && (
<div>
<div className="mb-1 text-text-secondary system-md-semibold">DSL URL</div>
<div className="mb-1 system-md-semibold text-text-secondary">DSL URL</div>
<Input
placeholder={t('importFromDSLUrlPlaceholder', { ns: 'app' }) || ''}
value={dslUrlValue}
@ -305,8 +305,8 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS
className="w-[480px]"
>
<div className="flex flex-col items-start gap-2 self-stretch pb-4">
<div className="text-text-primary title-2xl-semi-bold">{t('newApp.appCreateDSLErrorTitle', { ns: 'app' })}</div>
<div className="flex grow flex-col text-text-secondary system-md-regular">
<div className="title-2xl-semi-bold text-text-primary">{t('newApp.appCreateDSLErrorTitle', { ns: 'app' })}</div>
<div className="flex grow flex-col system-md-regular text-text-secondary">
<div>{t('newApp.appCreateDSLErrorPart1', { ns: 'app' })}</div>
<div>{t('newApp.appCreateDSLErrorPart2', { ns: 'app' })}</div>
<br />

View File

@ -6,9 +6,9 @@ import * as React from 'react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import AppIcon from '@/app/components/base/app-icon'
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
import Modal from '@/app/components/base/modal'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import AppsFull from '@/app/components/billing/apps-full-in-dialog'
import { useProviderContext } from '@/context/provider-context'
@ -76,12 +76,12 @@ const DuplicateAppModal = ({
onClose={noop}
className={cn('relative max-w-[480px]!', 'px-8')}
>
<div className="absolute right-4 top-4 cursor-pointer p-2" onClick={onHide}>
<div className="absolute top-4 right-4 cursor-pointer p-2" onClick={onHide}>
<RiCloseLine className="h-4 w-4 text-text-tertiary" />
</div>
<div className="relative mb-9 mt-3 text-xl font-semibold leading-[30px] text-text-primary">{t('duplicateTitle', { ns: 'app' })}</div>
<div className="system-sm-regular mb-9 text-text-secondary">
<div className="system-md-medium mb-2">{t('appCustomize.subTitle', { ns: 'explore' })}</div>
<div className="relative mt-3 mb-9 text-xl leading-[30px] font-semibold text-text-primary">{t('duplicateTitle', { ns: 'app' })}</div>
<div className="mb-9 system-sm-regular text-text-secondary">
<div className="mb-2 system-md-medium">{t('appCustomize.subTitle', { ns: 'explore' })}</div>
<div className="flex items-center justify-between space-x-2">
<AppIcon
size="large"

View File

@ -2,8 +2,8 @@
import { useEffect, useMemo, useState } from 'react'
import { trackEvent } from '@/app/components/base/amplitude'
import Button from '@/app/components/base/button'
import { MarkdownWithDirective } from '@/app/components/base/markdown-with-directive'
import { Button } from '@/app/components/base/ui/button'
import { cn } from '@/utils/classnames'
type InSiteMessageAction = 'link' | 'close'
@ -111,20 +111,20 @@ function InSiteMessage({
return (
<div
className={cn(
'fixed bottom-3 right-3 z-50 w-[360px] overflow-hidden rounded-xl border border-components-panel-border-subtle bg-components-panel-bg shadow-2xl backdrop-blur-[5px]',
'fixed right-3 bottom-3 z-50 w-[360px] overflow-hidden rounded-xl border border-components-panel-border-subtle bg-components-panel-bg shadow-2xl backdrop-blur-[5px]',
className,
)}
>
<div className="flex min-h-[128px] flex-col justify-end gap-0.5 bg-cover px-4 pb-3 pt-6 text-text-primary-on-surface" style={headerStyle}>
<div className="whitespace-pre-line title-3xl-bold">
<div className="flex min-h-[128px] flex-col justify-end gap-0.5 bg-cover px-4 pt-6 pb-3 text-text-primary-on-surface" style={headerStyle}>
<div className="title-3xl-bold whitespace-pre-line">
{normalizedTitle}
</div>
<div className="whitespace-pre-line body-md-regular">
<div className="body-md-regular whitespace-pre-line">
{normalizedSubtitle}
</div>
</div>
<div className="px-4 pb-2 pt-4 text-text-secondary body-md-regular">
<div className="px-4 pt-4 pb-2 body-md-regular text-text-secondary">
<MarkdownWithDirective markdown={main} />
</div>

View File

@ -4,8 +4,8 @@ import { RiCloseLine } from '@remixicon/react'
import * as React from 'react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import { LinkExternal02 } from '@/app/components/base/icons/src/vender/line/general'
import { Button } from '@/app/components/base/ui/button'
import { ACCOUNT_SETTING_TAB } from '@/app/components/header/account-setting/constants'
import { IS_CE_EDITION } from '@/config'
import { useModalContext } from '@/context/modal-context'
@ -29,7 +29,7 @@ const APIKeyInfoPanel: FC = () => {
return null
return (
<div className={cn('border-components-panel-border bg-components-panel-bg', 'relative mb-6 rounded-2xl border p-8 shadow-md ')}>
<div className={cn('border-components-panel-border bg-components-panel-bg', 'relative mb-6 rounded-2xl border p-8 shadow-md')}>
<div className={cn('text-[24px] font-semibold text-text-primary', isCloud ? 'flex h-8 items-center space-x-1' : 'mb-6 leading-8')}>
{isCloud && <em-emoji id="😀" />}
{isCloud
@ -56,7 +56,7 @@ const APIKeyInfoPanel: FC = () => {
</Button>
{!isCloud && (
<a
className="mt-2 flex h-[26px] items-center space-x-1 p-1 text-xs font-medium text-[#155EEF]"
className="mt-2 flex h-[26px] items-center space-x-1 p-1 text-xs font-medium text-[#155EEF]"
href="https://cloud.dify.ai/apps"
target="_blank"
rel="noopener noreferrer"
@ -67,7 +67,7 @@ const APIKeyInfoPanel: FC = () => {
)}
<div
onClick={() => setIsShow(false)}
className="absolute right-4 top-4 flex h-8 w-8 cursor-pointer items-center justify-center "
className="absolute top-4 right-4 flex h-8 w-8 cursor-pointer items-center justify-center"
>
<RiCloseLine className="h-4 w-4 text-text-tertiary" />
</div>

View File

@ -6,7 +6,6 @@ import type { ConfigParams } from './settings'
import type { AppDetailResponse } from '@/models/app'
import type { AppSSO } from '@/types/app'
import { RiArrowRightSLine, RiBookOpenLine, RiBuildingLine, RiEqualizer2Line, RiExternalLinkLine, RiGlobalLine, RiLockLine, RiPaintBrushLine, RiVerifiedBadgeLine, RiWindowLine } from '@remixicon/react'
import Button from '@/app/components/base/button'
import CopyFeedback from '@/app/components/base/copy-feedback'
import Divider from '@/app/components/base/divider'
import ShareQRCode from '@/app/components/base/qrcode'
@ -19,6 +18,7 @@ import {
AlertDialogDescription,
AlertDialogTitle,
} from '@/app/components/base/ui/alert-dialog'
import { Button } from '@/app/components/base/ui/button'
import {
Tooltip,
TooltipContent,

View File

@ -3,9 +3,9 @@ import type { FC } from 'react'
import { ArrowTopRightOnSquareIcon } from '@heroicons/react/24/outline'
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Modal from '@/app/components/base/modal'
import Tag from '@/app/components/base/tag'
import { Button } from '@/app/components/base/ui/button'
import { useDocLink } from '@/context/i18n'
import { AppModeEnum } from '@/types/app'
@ -54,17 +54,17 @@ const CustomizeModal: FC<IShareLinkProps> = ({
closable={true}
>
<div className="mt-4 w-full rounded-lg border-[0.5px] border-components-panel-border px-6 py-5">
<Tag bordered={true} hideBg={true} className="border-text-accent-secondary uppercase text-text-accent-secondary">
<Tag bordered={true} hideBg={true} className="border-text-accent-secondary text-text-accent-secondary uppercase">
{t(`${prefixCustomize}.way`, { ns: 'appOverview' })}
{' '}
1
</Tag>
<p className="system-sm-medium my-2 text-text-secondary">{t(`${prefixCustomize}.way1.name`, { ns: 'appOverview' })}</p>
<p className="my-2 system-sm-medium text-text-secondary">{t(`${prefixCustomize}.way1.name`, { ns: 'appOverview' })}</p>
<div className="flex py-4">
<StepNum>1</StepNum>
<div className="flex flex-col">
<div className="text-text-primary">{t(`${prefixCustomize}.way1.step1`, { ns: 'appOverview' })}</div>
<div className="mb-2 mt-1 text-xs text-text-tertiary">{t(`${prefixCustomize}.way1.step1Tip`, { ns: 'appOverview' })}</div>
<div className="mt-1 mb-2 text-xs text-text-tertiary">{t(`${prefixCustomize}.way1.step1Tip`, { ns: 'appOverview' })}</div>
<a href={`https://github.com/langgenius/${isChatApp ? 'webapp-conversation' : 'webapp-text-generator'}`} target="_blank" rel="noopener noreferrer">
<Button>
<GithubIcon className="mr-2 text-text-secondary" />
@ -77,10 +77,10 @@ const CustomizeModal: FC<IShareLinkProps> = ({
<StepNum>2</StepNum>
<div className="flex flex-col">
<div className="text-text-primary">{t(`${prefixCustomize}.way1.step2`, { ns: 'appOverview' })}</div>
<div className="mb-2 mt-1 text-xs text-text-tertiary">{t(`${prefixCustomize}.way1.step2Tip`, { ns: 'appOverview' })}</div>
<div className="mt-1 mb-2 text-xs text-text-tertiary">{t(`${prefixCustomize}.way1.step2Tip`, { ns: 'appOverview' })}</div>
<a href="https://vercel.com/docs/concepts/deployments/git/vercel-for-github" target="_blank" rel="noopener noreferrer">
<Button>
<div className="mr-1.5 border-b-12 border-l-[7px] border-r-[7px] border-t-0 border-solid border-text-primary border-l-transparent border-r-transparent border-t-transparent"></div>
<div className="mr-1.5 border-t-0 border-r-[7px] border-b-12 border-l-[7px] border-solid border-text-primary border-t-transparent border-r-transparent border-l-transparent"></div>
<span>{t(`${prefixCustomize}.way1.step2Operation`, { ns: 'appOverview' })}</span>
</Button>
</a>
@ -90,8 +90,8 @@ const CustomizeModal: FC<IShareLinkProps> = ({
<StepNum>3</StepNum>
<div className="flex w-full flex-col overflow-hidden">
<div className="text-text-primary">{t(`${prefixCustomize}.way1.step3`, { ns: 'appOverview' })}</div>
<div className="mb-2 mt-1 text-xs text-text-tertiary">{t(`${prefixCustomize}.way1.step3Tip`, { ns: 'appOverview' })}</div>
<pre className="box-border select-text overflow-x-scroll rounded-lg border-[0.5px] border-components-panel-border bg-background-section px-4 py-3 text-xs font-medium text-text-secondary">
<div className="mt-1 mb-2 text-xs text-text-tertiary">{t(`${prefixCustomize}.way1.step3Tip`, { ns: 'appOverview' })}</div>
<pre className="box-border overflow-x-scroll rounded-lg border-[0.5px] border-components-panel-border bg-background-section px-4 py-3 text-xs font-medium text-text-secondary select-text">
NEXT_PUBLIC_APP_ID=
{`'${appId}'`}
{' '}
@ -108,12 +108,12 @@ const CustomizeModal: FC<IShareLinkProps> = ({
</div>
<div className="mt-4 w-full rounded-lg border-[0.5px] border-components-panel-border px-6 py-5">
<Tag bordered={true} hideBg={true} className="border-text-accent-secondary uppercase text-text-accent-secondary">
<Tag bordered={true} hideBg={true} className="border-text-accent-secondary text-text-accent-secondary uppercase">
{t(`${prefixCustomize}.way`, { ns: 'appOverview' })}
{' '}
2
</Tag>
<p className="system-sm-medium my-2 text-text-secondary">{t(`${prefixCustomize}.way2.name`, { ns: 'appOverview' })}</p>
<p className="my-2 system-sm-medium text-text-secondary">{t(`${prefixCustomize}.way2.name`, { ns: 'appOverview' })}</p>
<Button
className="mt-2"
onClick={() =>

View File

@ -10,7 +10,6 @@ import { Trans, useTranslation } from 'react-i18next'
import ActionButton from '@/app/components/base/action-button'
import AppIcon from '@/app/components/base/app-icon'
import AppIconPicker from '@/app/components/base/app-icon-picker'
import Button from '@/app/components/base/button'
import Divider from '@/app/components/base/divider'
import { SparklesSoft } from '@/app/components/base/icons/src/public/common'
import Input from '@/app/components/base/input'
@ -20,6 +19,7 @@ import { SimpleSelect } from '@/app/components/base/select'
import Switch from '@/app/components/base/switch'
import Textarea from '@/app/components/base/textarea'
import Tooltip from '@/app/components/base/tooltip'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import { ACCOUNT_SETTING_TAB } from '@/app/components/header/account-setting/constants'
import { useModalContext } from '@/context/modal-context'
@ -241,14 +241,14 @@ const SettingsModal: FC<ISettingsModalProps> = ({
className="max-w-[520px] p-0"
>
{/* header */}
<div className="pb-3 pl-6 pr-5 pt-5">
<div className="pt-5 pr-5 pb-3 pl-6">
<div className="flex items-center gap-1">
<div className="grow text-text-primary title-2xl-semi-bold">{t(`${prefixSettings}.title`, { ns: 'appOverview' })}</div>
<div className="grow title-2xl-semi-bold text-text-primary">{t(`${prefixSettings}.title`, { ns: 'appOverview' })}</div>
<ActionButton className="shrink-0" onClick={onHide}>
<RiCloseLine className="h-4 w-4" />
</ActionButton>
</div>
<div className="mt-0.5 text-text-tertiary system-xs-regular">
<div className="mt-0.5 system-xs-regular text-text-tertiary">
<span>{t(`${prefixSettings}.modalTip`, { ns: 'appOverview' })}</span>
</div>
</div>
@ -257,7 +257,7 @@ const SettingsModal: FC<ISettingsModalProps> = ({
{/* name & icon */}
<div className="flex gap-4">
<div className="grow">
<div className={cn('mb-1 py-1 text-text-secondary system-sm-semibold')}>{t(`${prefixSettings}.webName`, { ns: 'appOverview' })}</div>
<div className={cn('mb-1 py-1 system-sm-semibold text-text-secondary')}>{t(`${prefixSettings}.webName`, { ns: 'appOverview' })}</div>
<Input
className="w-full"
value={inputInfo.title}
@ -277,32 +277,32 @@ const SettingsModal: FC<ISettingsModalProps> = ({
</div>
{/* description */}
<div className="relative">
<div className={cn('py-1 text-text-secondary system-sm-semibold')}>{t(`${prefixSettings}.webDesc`, { ns: 'appOverview' })}</div>
<div className={cn('py-1 system-sm-semibold text-text-secondary')}>{t(`${prefixSettings}.webDesc`, { ns: 'appOverview' })}</div>
<Textarea
className="mt-1"
value={inputInfo.desc}
onChange={e => onDesChange(e.target.value)}
placeholder={t(`${prefixSettings}.webDescPlaceholder`, { ns: 'appOverview' }) as string}
/>
<p className={cn('pb-0.5 text-text-tertiary body-xs-regular')}>{t(`${prefixSettings}.webDescTip`, { ns: 'appOverview' })}</p>
<p className={cn('pb-0.5 body-xs-regular text-text-tertiary')}>{t(`${prefixSettings}.webDescTip`, { ns: 'appOverview' })}</p>
</div>
<Divider className="my-0 h-px" />
{/* answer icon */}
{isChat && (
<div className="w-full">
<div className="flex items-center justify-between">
<div className={cn('py-1 text-text-secondary system-sm-semibold')}>{t('answerIcon.title', { ns: 'app' })}</div>
<div className={cn('py-1 system-sm-semibold text-text-secondary')}>{t('answerIcon.title', { ns: 'app' })}</div>
<Switch
value={inputInfo.use_icon_as_answer_icon}
onChange={v => setInputInfo({ ...inputInfo, use_icon_as_answer_icon: v })}
/>
</div>
<p className="pb-0.5 text-text-tertiary body-xs-regular">{t('answerIcon.description', { ns: 'app' })}</p>
<p className="pb-0.5 body-xs-regular text-text-tertiary">{t('answerIcon.description', { ns: 'app' })}</p>
</div>
)}
{/* language */}
<div className="flex items-center">
<div className={cn('grow py-1 text-text-secondary system-sm-semibold')}>{t(`${prefixSettings}.language`, { ns: 'appOverview' })}</div>
<div className={cn('grow py-1 system-sm-semibold text-text-secondary')}>{t(`${prefixSettings}.language`, { ns: 'appOverview' })}</div>
<SimpleSelect
wrapperClassName="w-[200px]"
items={languages.filter(item => item.supported)}
@ -315,8 +315,8 @@ const SettingsModal: FC<ISettingsModalProps> = ({
{isChat && (
<div className="flex items-center">
<div className="grow">
<div className={cn('py-1 text-text-secondary system-sm-semibold')}>{t(`${prefixSettings}.chatColorTheme`, { ns: 'appOverview' })}</div>
<div className="pb-0.5 text-text-tertiary body-xs-regular">{t(`${prefixSettings}.chatColorThemeDesc`, { ns: 'appOverview' })}</div>
<div className={cn('py-1 system-sm-semibold text-text-secondary')}>{t(`${prefixSettings}.chatColorTheme`, { ns: 'appOverview' })}</div>
<div className="pb-0.5 body-xs-regular text-text-tertiary">{t(`${prefixSettings}.chatColorThemeDesc`, { ns: 'appOverview' })}</div>
</div>
<div className="shrink-0">
<Input
@ -326,7 +326,7 @@ const SettingsModal: FC<ISettingsModalProps> = ({
placeholder="E.g #A020F0"
/>
<div className="flex items-center justify-between">
<p className={cn('text-text-tertiary body-xs-regular')}>{t(`${prefixSettings}.chatColorThemeInverted`, { ns: 'appOverview' })}</p>
<p className={cn('body-xs-regular text-text-tertiary')}>{t(`${prefixSettings}.chatColorThemeInverted`, { ns: 'appOverview' })}</p>
<Switch value={inputInfo.chatColorThemeInverted} onChange={v => setInputInfo({ ...inputInfo, chatColorThemeInverted: v })}></Switch>
</div>
</div>
@ -335,22 +335,22 @@ const SettingsModal: FC<ISettingsModalProps> = ({
{/* workflow detail */}
<div className="w-full">
<div className="flex items-center justify-between">
<div className={cn('py-1 text-text-secondary system-sm-semibold')}>{t(`${prefixSettings}.workflow.subTitle`, { ns: 'appOverview' })}</div>
<div className={cn('py-1 system-sm-semibold text-text-secondary')}>{t(`${prefixSettings}.workflow.subTitle`, { ns: 'appOverview' })}</div>
<Switch
disabled={!(appInfo.mode === AppModeEnum.WORKFLOW || appInfo.mode === AppModeEnum.ADVANCED_CHAT)}
value={inputInfo.show_workflow_steps}
onChange={v => setInputInfo({ ...inputInfo, show_workflow_steps: v })}
/>
</div>
<p className="pb-0.5 text-text-tertiary body-xs-regular">{t(`${prefixSettings}.workflow.showDesc`, { ns: 'appOverview' })}</p>
<p className="pb-0.5 body-xs-regular text-text-tertiary">{t(`${prefixSettings}.workflow.showDesc`, { ns: 'appOverview' })}</p>
</div>
{/* more settings switch */}
<Divider className="my-0 h-px" />
{!isShowMore && (
<div className="flex cursor-pointer items-center" onClick={() => setIsShowMore(true)}>
<div className="grow">
<div className={cn('py-1 text-text-secondary system-sm-semibold')}>{t(`${prefixSettings}.more.entry`, { ns: 'appOverview' })}</div>
<p className={cn('pb-0.5 text-text-tertiary body-xs-regular')}>
<div className={cn('py-1 system-sm-semibold text-text-secondary')}>{t(`${prefixSettings}.more.entry`, { ns: 'appOverview' })}</div>
<p className={cn('pb-0.5 body-xs-regular text-text-tertiary')}>
{t(`${prefixSettings}.more.copyRightPlaceholder`, { ns: 'appOverview' })}
{' '}
&
@ -368,7 +368,7 @@ const SettingsModal: FC<ISettingsModalProps> = ({
<div className="w-full">
<div className="flex items-center">
<div className="flex grow items-center">
<div className={cn('mr-1 py-1 text-text-secondary system-sm-semibold')}>{t(`${prefixSettings}.more.copyright`, { ns: 'appOverview' })}</div>
<div className={cn('mr-1 py-1 system-sm-semibold text-text-secondary')}>{t(`${prefixSettings}.more.copyright`, { ns: 'appOverview' })}</div>
{/* upgrade button */}
{enableBilling && isFreePlan && (
<div className="h-[18px] select-none">
@ -397,7 +397,7 @@ const SettingsModal: FC<ISettingsModalProps> = ({
/>
</Tooltip>
</div>
<p className="pb-0.5 text-text-tertiary body-xs-regular">{t(`${prefixSettings}.more.copyrightTip`, { ns: 'appOverview' })}</p>
<p className="pb-0.5 body-xs-regular text-text-tertiary">{t(`${prefixSettings}.more.copyrightTip`, { ns: 'appOverview' })}</p>
{inputInfo.copyrightSwitchValue && (
<Input
className="mt-2 h-10"
@ -409,8 +409,8 @@ const SettingsModal: FC<ISettingsModalProps> = ({
</div>
{/* privacy policy */}
<div className="w-full">
<div className={cn('py-1 text-text-secondary system-sm-semibold')}>{t(`${prefixSettings}.more.privacyPolicy`, { ns: 'appOverview' })}</div>
<p className={cn('pb-0.5 text-text-tertiary body-xs-regular')}>
<div className={cn('py-1 system-sm-semibold text-text-secondary')}>{t(`${prefixSettings}.more.privacyPolicy`, { ns: 'appOverview' })}</div>
<p className={cn('pb-0.5 body-xs-regular text-text-tertiary')}>
<Trans
i18nKey={`${prefixSettings}.more.privacyPolicyTip`}
ns="appOverview"
@ -426,8 +426,8 @@ const SettingsModal: FC<ISettingsModalProps> = ({
</div>
{/* custom disclaimer */}
<div className="w-full">
<div className={cn('py-1 text-text-secondary system-sm-semibold')}>{t(`${prefixSettings}.more.customDisclaimer`, { ns: 'appOverview' })}</div>
<p className={cn('pb-0.5 text-text-tertiary body-xs-regular')}>{t(`${prefixSettings}.more.customDisclaimerTip`, { ns: 'appOverview' })}</p>
<div className={cn('py-1 system-sm-semibold text-text-secondary')}>{t(`${prefixSettings}.more.customDisclaimer`, { ns: 'appOverview' })}</div>
<p className={cn('pb-0.5 body-xs-regular text-text-tertiary')}>{t(`${prefixSettings}.more.customDisclaimerTip`, { ns: 'appOverview' })}</p>
<Textarea
className="mt-1"
value={inputInfo.customDisclaimer}

View File

@ -7,12 +7,12 @@ import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useStore as useAppStore } from '@/app/components/app/store'
import AppIcon from '@/app/components/base/app-icon'
import Button from '@/app/components/base/button'
import Checkbox from '@/app/components/base/checkbox'
import Confirm from '@/app/components/base/confirm'
import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
import Input from '@/app/components/base/input'
import Modal from '@/app/components/base/modal'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import AppsFull from '@/app/components/billing/apps-full-in-dialog'
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
@ -98,20 +98,20 @@ const SwitchAppModal = ({ show, appDetail, inAppDetail = false, onSuccess, onClo
isShow={show}
onClose={noop}
>
<div className="absolute right-4 top-4 cursor-pointer p-2" onClick={onClose}>
<div className="absolute top-4 right-4 cursor-pointer p-2" onClick={onClose}>
<RiCloseLine className="h-4 w-4 text-text-tertiary" />
</div>
<div className="h-12 w-12 rounded-xl border-[0.5px] border-divider-regular bg-background-default-burn p-3 shadow-xl">
<AlertTriangle className="h-6 w-6 text-[rgb(247,144,9)]" />
</div>
<div className="relative mt-3 text-xl font-semibold leading-[30px] text-text-primary">{t('switch', { ns: 'app' })}</div>
<div className="relative mt-3 text-xl leading-[30px] font-semibold text-text-primary">{t('switch', { ns: 'app' })}</div>
<div className="my-1 text-sm leading-5 text-text-tertiary">
<span>{t('switchTipStart', { ns: 'app' })}</span>
<span className="font-medium text-text-secondary">{t('switchTip', { ns: 'app' })}</span>
<span>{t('switchTipEnd', { ns: 'app' })}</span>
</div>
<div className="pb-4">
<div className="py-2 text-sm font-medium leading-[20px] text-text-primary">{t('switchLabel', { ns: 'app' })}</div>
<div className="py-2 text-sm leading-[20px] font-medium text-text-primary">{t('switchLabel', { ns: 'app' })}</div>
<div className="flex items-center justify-between space-x-2">
<AppIcon
size="large"
@ -152,7 +152,7 @@ const SwitchAppModal = ({ show, appDetail, inAppDetail = false, onSuccess, onClo
</div>
<div className="flex items-center">
<Button className="mr-2" onClick={onClose}>{t('newApp.Cancel', { ns: 'app' })}</Button>
<Button className="border-red-700" disabled={isAppsFull || !name} variant="warning" onClick={goStart}>{t('switchStart', { ns: 'app' })}</Button>
<Button className="border-red-700" disabled={isAppsFull || !name} variant="primary" destructive onClick={goStart}>{t('switchStart', { ns: 'app' })}</Button>
</div>
</div>
</Modal>

View File

@ -6,7 +6,7 @@ import {
} from '@remixicon/react'
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import { Button } from '@/app/components/base/ui/button'
type INoDataProps = {
onStartCreateContent: () => void
@ -18,14 +18,14 @@ const NoData: FC<INoDataProps> = ({
const { t } = useTranslation()
return (
<div className="rounded-xl bg-background-section-burn p-6 ">
<div className="rounded-xl bg-background-section-burn p-6">
<div className="flex h-10 w-10 items-center justify-center radius-lg border-[0.5px] border-components-card-border bg-components-card-bg-alt shadow-lg backdrop-blur-xs">
<RiBookmark3Line className="h-4 w-4 text-text-accent" />
</div>
<div className="mt-3">
<span className="system-xl-semibold text-text-secondary">{t('generation.savedNoData.title', { ns: 'share' })}</span>
</div>
<div className="system-sm-regular mt-1 text-text-tertiary">
<div className="mt-1 system-sm-regular text-text-tertiary">
{t('generation.savedNoData.description', { ns: 'share' })}
</div>
<Button

View File

@ -6,9 +6,9 @@ import { RiImageCircleAiLine } from '@remixicon/react'
import { noop } from 'es-toolkit/function'
import { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Button } from '@/app/components/base/ui/button'
import { DISABLE_UPLOAD_IMAGE_AS_ICON } from '@/config'
import { cn } from '@/utils/classnames'
import Button from '../button'
import Divider from '../divider'
import EmojiPickerInner from '../emoji-picker/Inner'
import { useLocalFileUploader } from '../image-uploader/hooks'
@ -123,7 +123,7 @@ const AppIconPicker: FC<AppIconPickerProps> = ({
type="button"
key={tab.key}
className={cn(
'system-sm-medium flex h-8 flex-1 shrink-0 items-center justify-center rounded-lg p-2 text-text-tertiary',
'flex h-8 flex-1 shrink-0 items-center justify-center rounded-lg p-2 system-sm-medium text-text-tertiary',
activeTab === tab.key && 'bg-components-main-nav-nav-button-bg-active text-text-accent shadow-md',
)}
onClick={() => setActiveTab(tab.key as AppIconType)}

View File

@ -1,49 +0,0 @@
import { fireEvent, render, screen } from '@testing-library/react'
import AddButton from '../add-button'
describe('AddButton', () => {
describe('Rendering', () => {
it('should render without crashing', () => {
const { container } = render(<AddButton onClick={vi.fn()} />)
expect(container.firstChild).toBeInTheDocument()
})
it('should render an add icon', () => {
render(<AddButton onClick={vi.fn()} />)
const iconSpan = screen.getByTestId('add-button').querySelector('span')
expect(iconSpan).toBeInTheDocument()
})
})
describe('Props', () => {
it('should apply custom className', () => {
const { container } = render(<AddButton onClick={vi.fn()} className="my-custom" />)
expect(container.firstChild).toHaveClass('my-custom')
})
it('should retain base classes when custom className is applied', () => {
const { container } = render(<AddButton onClick={vi.fn()} className="my-custom" />)
expect(container.firstChild).toHaveClass('cursor-pointer')
expect(container.firstChild).toHaveClass('rounded-md')
expect(container.firstChild).toHaveClass('select-none')
})
})
describe('User Interactions', () => {
it('should call onClick when clicked', () => {
const onClick = vi.fn()
const { container } = render(<AddButton onClick={onClick} />)
fireEvent.click(container.firstChild!)
expect(onClick).toHaveBeenCalledTimes(1)
})
it('should call onClick multiple times on repeated clicks', () => {
const onClick = vi.fn()
const { container } = render(<AddButton onClick={onClick} />)
fireEvent.click(container.firstChild!)
fireEvent.click(container.firstChild!)
fireEvent.click(container.firstChild!)
expect(onClick).toHaveBeenCalledTimes(3)
})
})
})

View File

@ -1,52 +0,0 @@
import { fireEvent, render, screen } from '@testing-library/react'
import SyncButton from '../sync-button'
describe('SyncButton', () => {
describe('Rendering', () => {
it('should render without crashing', () => {
const { container } = render(<SyncButton onClick={vi.fn()} />)
expect(container.firstChild).toBeInTheDocument()
})
it('should render a refresh icon', () => {
render(<SyncButton onClick={vi.fn()} />)
const iconSpan = screen.getByTestId('sync-button').querySelector('span')
expect(iconSpan).toBeInTheDocument()
})
})
describe('Props', () => {
it('should apply custom className', () => {
render(<SyncButton onClick={vi.fn()} className="my-custom" />)
const clickableDiv = screen.getByTestId('sync-button')
expect(clickableDiv).toHaveClass('my-custom')
})
it('should retain base classes when custom className is applied', () => {
render(<SyncButton onClick={vi.fn()} className="my-custom" />)
const clickableDiv = screen.getByTestId('sync-button')
expect(clickableDiv).toHaveClass('rounded-md')
expect(clickableDiv).toHaveClass('select-none')
})
})
describe('User Interactions', () => {
it('should call onClick when clicked', () => {
const onClick = vi.fn()
render(<SyncButton onClick={onClick} />)
const clickableDiv = screen.getByTestId('sync-button')
fireEvent.click(clickableDiv)
expect(onClick).toHaveBeenCalledTimes(1)
})
it('should call onClick multiple times on repeated clicks', () => {
const onClick = vi.fn()
render(<SyncButton onClick={onClick} />)
const clickableDiv = screen.getByTestId('sync-button')
fireEvent.click(clickableDiv)
fireEvent.click(clickableDiv)
fireEvent.click(clickableDiv)
expect(onClick).toHaveBeenCalledTimes(3)
})
})
})

View File

@ -1,52 +0,0 @@
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import AddButton from './add-button'
const meta = {
title: 'Base/General/AddButton',
component: AddButton,
parameters: {
layout: 'centered',
docs: {
description: {
component: 'Compact icon-only button used for inline “add” actions in lists, cards, and modals.',
},
},
},
tags: ['autodocs'],
argTypes: {
className: {
control: 'text',
description: 'Extra classes appended to the clickable container.',
},
onClick: {
control: false,
description: 'Triggered when the add button is pressed.',
},
},
args: {
onClick: () => console.log('Add button clicked'),
},
} satisfies Meta<typeof AddButton>
export default meta
type Story = StoryObj<typeof meta>
export const Default: Story = {
args: {
className: 'bg-white/80 shadow-sm backdrop-blur-xs',
},
}
export const InToolbar: Story = {
render: args => (
<div className="flex items-center gap-2 rounded-lg border border-divider-subtle bg-components-panel-bg p-3">
<span className="text-xs text-text-tertiary">Attachments</span>
<div className="ml-auto flex items-center gap-2">
<AddButton {...args} />
</div>
</div>
),
args: {
className: 'border border-dashed border-primary-200',
},
}

View File

@ -1,21 +0,0 @@
'use client'
import type { FC } from 'react'
import * as React from 'react'
import { cn } from '@/utils/classnames'
type Props = {
className?: string
onClick: () => void
}
const AddButton: FC<Props> = ({
className,
onClick,
}) => {
return (
<div className={cn(className, 'cursor-pointer select-none rounded-md p-1 hover:bg-state-base-hover')} onClick={onClick} data-testid="add-button">
<span className="i-ri-add-line h-4 w-4 text-text-tertiary" />
</div>
)
}
export default React.memo(AddButton)

View File

@ -1,57 +0,0 @@
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import SyncButton from './sync-button'
const meta = {
title: 'Base/General/SyncButton',
component: SyncButton,
parameters: {
layout: 'centered',
docs: {
description: {
component: 'Icon-only refresh button that surfaces a tooltip and is used for manual sync actions across the UI.',
},
},
},
tags: ['autodocs'],
argTypes: {
className: {
control: 'text',
description: 'Additional classes appended to the clickable container.',
},
popupContent: {
control: 'text',
description: 'Tooltip text shown on hover.',
},
onClick: {
control: false,
description: 'Triggered when the sync button is pressed.',
},
},
args: {
popupContent: 'Sync now',
onClick: () => console.log('Sync button clicked'),
},
} satisfies Meta<typeof SyncButton>
export default meta
type Story = StoryObj<typeof meta>
export const Default: Story = {
args: {
className: 'bg-white/80 shadow-sm backdrop-blur-xs',
},
}
export const InHeader: Story = {
render: args => (
<div className="flex items-center gap-2 rounded-lg border border-divider-subtle bg-components-panel-bg p-3">
<span className="text-xs text-text-tertiary">Logs</span>
<div className="ml-auto flex items-center gap-2">
<SyncButton {...args} />
</div>
</div>
),
args: {
popupContent: 'Refresh logs',
},
}

View File

@ -1,26 +0,0 @@
'use client'
import type { FC } from 'react'
import * as React from 'react'
import TooltipPlus from '@/app/components/base/tooltip'
import { cn } from '@/utils/classnames'
type Props = {
className?: string
popupContent?: string
onClick: () => void
}
const SyncButton: FC<Props> = ({
className,
popupContent = '',
onClick,
}) => {
return (
<TooltipPlus popupContent={popupContent}>
<div className={cn(className, 'cursor-pointer select-none rounded-md p-1 hover:bg-state-base-hover')} onClick={onClick} data-testid="sync-button">
<span className="i-ri-refresh-line h-4 w-4 text-text-tertiary" />
</div>
</TooltipPlus>
)
}
export default React.memo(SyncButton)

View File

@ -1,9 +1,9 @@
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import InputsFormContent from '@/app/components/base/chat/chat-with-history/inputs-form/content'
import Divider from '@/app/components/base/divider'
import { Message3Fill } from '@/app/components/base/icons/src/public/other'
import { Button } from '@/app/components/base/ui/button'
import { cn } from '@/utils/classnames'
import { useChatWithHistoryContext } from '../context'
@ -43,12 +43,12 @@ const InputsFormNode = ({
)}
>
<Message3Fill className="h-6 w-6 shrink-0" />
<div className="system-xl-semibold grow text-text-secondary">{t('chat.chatSettingsTitle', { ns: 'share' })}</div>
<div className="grow system-xl-semibold text-text-secondary">{t('chat.chatSettingsTitle', { ns: 'share' })}</div>
{collapsed && (
<Button className="uppercase text-text-tertiary" size="small" variant="ghost" onClick={() => setCollapsed(false)}>{t('operation.edit', { ns: 'common' })}</Button>
<Button className="text-text-tertiary uppercase" size="small" variant="ghost" onClick={() => setCollapsed(false)}>{t('operation.edit', { ns: 'common' })}</Button>
)}
{!collapsed && currentConversationId && (
<Button className="uppercase text-text-tertiary" size="small" variant="ghost" onClick={() => setCollapsed(true)}>{t('operation.close', { ns: 'common' })}</Button>
<Button className="text-text-tertiary uppercase" size="small" variant="ghost" onClick={() => setCollapsed(true)}>{t('operation.close', { ns: 'common' })}</Button>
)}
</div>
{!collapsed && (

View File

@ -83,12 +83,18 @@ describe('RenameModal', () => {
it('shows loading state when saveLoading is true', () => {
render(<RenameModal {...defaultProps} saveLoading />)
expect(screen.getByRole('status')).toBeInTheDocument()
const saveButton = screen.getByRole('button', { name: 'common.operation.save' })
expect(saveButton).toBeDisabled()
expect(saveButton).toHaveAttribute('aria-busy', 'true')
expect(saveButton.querySelector('.animate-spin')).toBeInTheDocument()
})
it('hides loading state when saveLoading is false', () => {
render(<RenameModal {...defaultProps} saveLoading={false} />)
expect(screen.queryByRole('status')).not.toBeInTheDocument()
const saveButton = screen.getByRole('button', { name: 'common.operation.save' })
expect(saveButton).not.toBeDisabled()
expect(saveButton).not.toHaveAttribute('aria-busy')
expect(saveButton.querySelector('.animate-spin')).not.toBeInTheDocument()
})
it('keeps edited name when parent rerenders with different name prop', async () => {

View File

@ -11,11 +11,11 @@ import {
import { useTranslation } from 'react-i18next'
import ActionButton from '@/app/components/base/action-button'
import AppIcon from '@/app/components/base/app-icon'
import Button from '@/app/components/base/button'
import List from '@/app/components/base/chat/chat-with-history/sidebar/list'
import RenameModal from '@/app/components/base/chat/chat-with-history/sidebar/rename-modal'
import Confirm from '@/app/components/base/confirm'
import DifyLogo from '@/app/components/base/logo/dify-logo'
import { Button } from '@/app/components/base/ui/button'
import MenuDropdown from '@/app/components/share/text-generation/menu-dropdown'
import { useGlobalPublicStore } from '@/context/global-public-context'
import { cn } from '@/utils/classnames'
@ -100,7 +100,7 @@ const Sidebar = ({ isPanel, panelVisible }: Props) => {
imageUrl={appData?.site.icon_url}
/>
</div>
<div className={cn('system-md-semibold grow truncate text-text-secondary')}>{appData?.site.title}</div>
<div className={cn('grow truncate system-md-semibold text-text-secondary')}>{appData?.site.title}</div>
{!isMobile && isSidebarCollapsed && (
<ActionButton size="l" onClick={() => handleSidebarCollapse(false)}>
<RiExpandRightLine className="h-[18px] w-[18px]" />

View File

@ -3,9 +3,9 @@ import type { FC } from 'react'
import * as React from 'react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
import Modal from '@/app/components/base/modal'
import { Button } from '@/app/components/base/ui/button'
type IRenameModalProps = {
isShow: boolean
@ -32,7 +32,7 @@ const RenameModal: FC<IRenameModalProps> = ({
isShow={isShow}
onClose={onClose}
>
<div className="mt-6 text-sm font-medium leading-[21px] text-text-primary">{t('chat.conversationName', { ns: 'common' })}</div>
<div className="mt-6 text-sm leading-[21px] font-medium text-text-primary">{t('chat.conversationName', { ns: 'common' })}</div>
<Input
className="mt-2 h-10 w-full"
value={tempName}

View File

@ -1,10 +1,10 @@
'use client'
import type { HumanInputFormProps } from './type'
import type { ButtonProps } from '@/app/components/base/button'
import type { ButtonProps } from '@/app/components/base/ui/button'
import type { UserAction } from '@/app/components/workflow/nodes/human-input/types'
import * as React from 'react'
import { useCallback, useState } from 'react'
import Button from '@/app/components/base/button'
import { Button } from '@/app/components/base/ui/button'
import ContentItem from './content-item'
import { getButtonStyle, initializeInputs, splitByOutputVar } from './utils'

View File

@ -11,8 +11,8 @@ import {
import { noop } from 'es-toolkit/function'
import { memo } from 'react'
import ActionButton from '@/app/components/base/action-button'
import Button from '@/app/components/base/button'
import { FileUploaderInChatInput } from '@/app/components/base/file-uploader'
import { Button } from '@/app/components/base/ui/button'
import { cn } from '@/utils/classnames'
type OperationProps = {

View File

@ -17,7 +17,7 @@ import { memo } from 'react'
import { useTranslation } from 'react-i18next'
import { useShallow } from 'zustand/react/shallow'
import { useStore as useAppStore } from '@/app/components/app/store'
import Button from '@/app/components/base/button'
import { Button } from '@/app/components/base/ui/button'
import { cn } from '@/utils/classnames'
import Answer from './answer'
import ChatInputArea from './chat-input-area'

View File

@ -17,9 +17,9 @@ import Textarea from 'react-textarea-autosize'
import { FileList } from '@/app/components/base/file-uploader'
import { User } from '@/app/components/base/icons/src/public/avatar'
import { Markdown } from '@/app/components/base/markdown'
import { Button } from '@/app/components/base/ui/button'
import { cn } from '@/utils/classnames'
import ActionButton from '../../action-button'
import Button from '../../button'
import { toast } from '../../ui/toast'
import { CssTransform } from '../embedded-chatbot/theme/utils'
import ContentSwitch from './content-switch'
@ -207,10 +207,10 @@ const Question: FC<QuestionProps> = ({
? <Markdown content={content} />
: (
<div className="flex flex-col gap-4">
<div className="max-h-[158px] overflow-y-auto overflow-x-hidden pr-1">
<div className="max-h-[158px] overflow-x-hidden overflow-y-auto pr-1">
<Textarea
className={cn(
'w-full resize-none bg-transparent p-0 leading-7 text-text-primary outline-hidden body-lg-regular',
'w-full resize-none bg-transparent p-0 body-lg-regular leading-7 text-text-primary outline-hidden',
)}
autoFocus
minRows={1}

View File

@ -2,8 +2,8 @@ import type { FC } from 'react'
import type { OnSend } from '../types'
import { memo } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Divider from '@/app/components/base/divider'
import { Button } from '@/app/components/base/ui/button'
type TryToAskProps = {
suggestedQuestions: string[]
@ -19,7 +19,7 @@ const TryToAsk: FC<TryToAskProps> = ({
<div className="mb-2 py-2">
<div className="mb-2.5 flex items-center justify-between gap-2">
<Divider bgStyle="gradient" className="h-px w-auto! grow rotate-180" />
<div className="system-xs-medium-uppercase shrink-0 text-text-tertiary">{t('feature.suggestedQuestionsAfterAnswer.tryToAsk', { ns: 'appDebug' })}</div>
<div className="shrink-0 system-xs-medium-uppercase text-text-tertiary">{t('feature.suggestedQuestionsAfterAnswer.tryToAsk', { ns: 'appDebug' })}</div>
<Divider bgStyle="gradient" className="h-px w-auto! grow" />
</div>
<div className="flex flex-wrap justify-center">
@ -29,7 +29,7 @@ const TryToAsk: FC<TryToAskProps> = ({
size="small"
key={index}
variant="secondary-accent"
className="mb-1 mr-1 last:mr-0"
className="mr-1 mb-1 last:mr-0"
onClick={() => onSend(suggestQuestion)}
>
{suggestQuestion}

View File

@ -1,8 +1,8 @@
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import InputsFormContent from '@/app/components/base/chat/embedded-chatbot/inputs-form/content'
import Divider from '@/app/components/base/divider'
import { Button } from '@/app/components/base/ui/button'
import { AppSourceType } from '@/service/share'
import { cn } from '@/utils/classnames'
import { useEmbeddedChatbotContext } from '../context'
@ -49,10 +49,10 @@ const InputsFormNode = ({
)}
>
<div className="i-custom-public-other-message-3-fill h-6 w-6 shrink-0" />
<div className="grow text-text-secondary system-xl-semibold">{t('chat.chatSettingsTitle', { ns: 'share' })}</div>
<div className="grow system-xl-semibold text-text-secondary">{t('chat.chatSettingsTitle', { ns: 'share' })}</div>
{collapsed && (
<Button
className="uppercase text-text-tertiary"
className="text-text-tertiary uppercase"
size="small"
variant="ghost"
onClick={() => setCollapsed(false)}
@ -63,7 +63,7 @@ const InputsFormNode = ({
)}
{!collapsed && currentConversationId && (
<Button
className="uppercase text-text-tertiary"
className="text-text-tertiary uppercase"
size="small"
variant="ghost"
onClick={() => setCollapsed(true)}

View File

@ -5,9 +5,9 @@ import { useTranslation } from 'react-i18next'
import Badge from '@/app/components/base/badge'
import Checkbox from '@/app/components/base/checkbox'
import SearchInput from '@/app/components/base/search-input'
import { Button } from '@/app/components/base/ui/button'
import SearchMenu from '@/assets/search-menu.svg'
import { cn } from '@/utils/classnames'
import Button from '../button'
type CheckboxListOption = {
label: string
@ -100,12 +100,12 @@ const CheckboxList: FC<CheckboxListProps> = ({
return (
<div className={cn('flex w-full flex-col gap-1', containerClassName)}>
{label && (
<div className="text-text-secondary system-sm-medium">
<div className="system-sm-medium text-text-secondary">
{label}
</div>
)}
{description && (
<div className="text-text-tertiary body-xs-regular">
<div className="body-xs-regular text-text-tertiary">
{description}
</div>
)}
@ -126,7 +126,7 @@ const CheckboxList: FC<CheckboxListProps> = ({
? (
<div className="flex min-w-0 flex-1 items-center gap-1">
{title && (
<span className="truncate leading-5 text-text-secondary system-xs-semibold-uppercase">
<span className="truncate system-xs-semibold-uppercase leading-5 text-text-secondary">
{title}
</span>
)}
@ -138,7 +138,7 @@ const CheckboxList: FC<CheckboxListProps> = ({
</div>
)
: (
<div className="flex-1 leading-6 text-text-secondary system-sm-medium-uppercase">
<div className="flex-1 system-sm-medium-uppercase leading-6 text-text-secondary">
{
filteredOptions.length > 0
? t('operation.searchCount', { ns: 'common', count: filteredOptions.length, content: title })
@ -169,7 +169,7 @@ const CheckboxList: FC<CheckboxListProps> = ({
? (
<div className="flex flex-col items-center justify-center gap-2">
<img alt="search menu" src={SearchMenu.src} width={32} />
<span className="text-text-secondary system-sm-regular">{t('operation.noSearchResults', { ns: 'common', content: title })}</span>
<span className="system-sm-regular text-text-secondary">{t('operation.noSearchResults', { ns: 'common', content: title })}</span>
<Button variant="secondary-accent" size="small" onClick={() => setSearchQuery('')}>{t('operation.resetKeywords', { ns: 'common' })}</Button>
</div>
)
@ -203,7 +203,7 @@ const CheckboxList: FC<CheckboxListProps> = ({
id={option.value}
/>
<div
className="flex-1 truncate text-text-secondary system-sm-medium"
className="flex-1 truncate system-sm-medium text-text-secondary"
title={option.label}
>
{option.label}

View File

@ -1,7 +1,7 @@
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import { useState } from 'react'
import { Button } from '@/app/components/base/ui/button'
import Confirm from '.'
import Button from '../button'
const meta = {
title: 'Base/Feedback/Confirm',

View File

@ -7,7 +7,7 @@ import * as React from 'react'
import { useEffect, useRef, useState } from 'react'
import { createPortal } from 'react-dom'
import { useTranslation } from 'react-i18next'
import Button from '../button'
import { Button } from '@/app/components/base/ui/button'
import Tooltip from '../tooltip'
/** @deprecated Use `@/app/components/base/ui/alert-dialog` instead. */
@ -122,7 +122,7 @@ function Confirm({
>
<div ref={dialogRef} className="relative w-full max-w-[480px] overflow-hidden">
<div className="shadows-shadow-lg flex max-w-full flex-col items-start rounded-2xl border-[0.5px] border-solid border-components-panel-border bg-components-panel-bg">
<div className="flex flex-col items-start gap-2 self-stretch pb-4 pl-6 pr-6 pt-6">
<div className="flex flex-col items-start gap-2 self-stretch pt-6 pr-6 pb-4 pl-6">
<Tooltip
popupContent={title}
disabled={!isTitleTruncated}
@ -130,19 +130,19 @@ function Confirm({
asChild={false}
triggerClassName="w-full"
>
<div ref={titleRef} className="title-2xl-semi-bold w-full truncate text-text-primary">
<div ref={titleRef} className="w-full truncate title-2xl-semi-bold text-text-primary">
{title}
</div>
</Tooltip>
<div className="w-full whitespace-pre-wrap wrap-break-word text-text-tertiary system-md-regular">{content}</div>
<div className="w-full system-md-regular wrap-break-word whitespace-pre-wrap text-text-tertiary">{content}</div>
{confirmInputLabel && (
<div className="mt-2">
<label className="mb-1 block text-text-secondary system-sm-regular">
<label className="mb-1 block system-sm-regular text-text-secondary">
{confirmInputLabel}
</label>
<input
type="text"
className="border-components-input-border bg-components-input-bg focus:border-components-input-border-focus focus:ring-components-input-border-focus h-9 w-full rounded-lg border px-3 text-sm text-text-primary placeholder:text-text-quaternary focus:outline-hidden focus:ring-1"
className="border-components-input-border bg-components-input-bg focus:border-components-input-border-focus focus:ring-components-input-border-focus h-9 w-full rounded-lg border px-3 text-sm text-text-primary placeholder:text-text-quaternary focus:ring-1 focus:outline-hidden"
placeholder={confirmInputPlaceholder}
value={confirmInputValue}
onChange={e => onConfirmInputChange?.(e.target.value)}

View File

@ -3,8 +3,8 @@ import type { DatePickerFooterProps } from '../types'
import { RiTimeLine } from '@remixicon/react'
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import { Button } from '@/app/components/base/ui/button'
import { cn } from '@/utils/classnames'
import Button from '../../button'
import { ViewType } from '../types'
const Footer: FC<DatePickerFooterProps> = ({
@ -27,8 +27,8 @@ const Footer: FC<DatePickerFooterProps> = ({
{needTimePicker && (
<button
type="button"
className="system-xs-medium flex items-center gap-x-px rounded-md border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg px-1.5
py-1 text-components-button-secondary-accent-text shadow-xs shadow-shadow-shadow-3 backdrop-blur-[5px]"
className="flex items-center gap-x-px rounded-md border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg px-1.5 py-1
system-xs-medium text-components-button-secondary-accent-text shadow-xs shadow-shadow-shadow-3 backdrop-blur-[5px]"
onClick={handleClickTimePicker}
>
<RiTimeLine className="h-3.5 w-3.5" />
@ -40,7 +40,7 @@ const Footer: FC<DatePickerFooterProps> = ({
{/* Now */}
<button
type="button"
className="system-xs-medium flex items-center justify-center px-1.5 py-1 text-components-button-secondary-accent-text"
className="flex items-center justify-center px-1.5 py-1 system-xs-medium text-components-button-secondary-accent-text"
onClick={handleSelectCurrentDate}
>
<span className="px-[3px]">{t('operation.now', { ns: 'time' })}</span>

View File

@ -2,7 +2,7 @@ import type { FC } from 'react'
import type { TimePickerFooterProps } from '../types'
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import Button from '../../button'
import { Button } from '@/app/components/base/ui/button'
const Footer: FC<TimePickerFooterProps> = ({
handleSelectCurrentTime,

View File

@ -2,7 +2,7 @@ import type { FC } from 'react'
import type { YearAndMonthPickerFooterProps } from '../types'
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import Button from '../../button'
import { Button } from '@/app/components/base/ui/button'
const Footer: FC<YearAndMonthPickerFooterProps> = ({
handleYearMonthCancel,

View File

@ -1,8 +1,8 @@
'use client'
import { Dialog, DialogBackdrop, DialogTitle } from '@headlessui/react'
import { useTranslation } from 'react-i18next'
import { Button } from '@/app/components/base/ui/button'
import { cn } from '@/utils/classnames'
import Button from '../button'
export type IDrawerProps = {
title?: string
@ -73,7 +73,7 @@ export default function Drawer({
{title && (
<DialogTitle
as="h3"
className="text-lg font-medium leading-6 text-text-primary"
className="text-lg leading-6 font-medium text-text-primary"
>
{title}
</DialogTitle>

View File

@ -4,9 +4,9 @@ import { noop } from 'es-toolkit/function'
import * as React from 'react'
import { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Divider from '@/app/components/base/divider'
import Modal from '@/app/components/base/modal'
import { Button } from '@/app/components/base/ui/button'
import { cn } from '@/utils/classnames'
import EmojiPickerInner from './Inner'
@ -45,7 +45,7 @@ const EmojiPicker: FC<IEmojiPickerProps> = ({
className="pt-3"
onSelect={handleSelectEmoji}
/>
<Divider className="mb-0 mt-3" />
<Divider className="mt-3 mb-0" />
<div className="flex w-full items-center justify-center gap-2 p-3">
<Button
className="w-full"

View File

@ -4,7 +4,7 @@ import { RiAlertLine, RiBugLine } from '@remixicon/react'
import * as React from 'react'
import { useCallback, useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import { Button } from '@/app/components/base/ui/button'
import { IS_DEV } from '@/config'
import { cn } from '@/utils/classnames'
@ -151,14 +151,14 @@ class ErrorBoundaryInner extends React.Component<
<div className="rounded-lg bg-gray-100 p-4">
<div className="mb-2">
<span className="font-mono text-xs font-semibold text-gray-600">{copy.error}</span>
<pre className="mt-1 overflow-auto whitespace-pre-wrap font-mono text-xs text-gray-800">
<pre className="mt-1 overflow-auto font-mono text-xs whitespace-pre-wrap text-gray-800">
{error.toString()}
</pre>
</div>
{errorInfo && (
<div>
<span className="font-mono text-xs font-semibold text-gray-600">{copy.componentStack}</span>
<pre className="mt-1 max-h-40 overflow-auto whitespace-pre-wrap font-mono text-xs text-gray-700">
<pre className="mt-1 max-h-40 overflow-auto font-mono text-xs whitespace-pre-wrap text-gray-700">
{errorInfo.componentStack}
</pre>
</div>

View File

@ -4,8 +4,8 @@ import type { AnnotationReplyConfig } from '@/models/debug'
import * as React from 'react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Modal from '@/app/components/base/modal'
import { Button } from '@/app/components/base/ui/button'
import { toast } from '@/app/components/base/ui/toast'
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
@ -59,7 +59,7 @@ const ConfigParamModal: FC<Props> = ({ isShow, onHide: doHide, onSave, isInit, a
}
return (
<Modal isShow={isShow} onClose={onHide} className="!mt-14 !w-[640px] !max-w-none !p-6">
<div className="mb-2 text-text-primary title-2xl-semi-bold">
<div className="mb-2 title-2xl-semi-bold text-text-primary">
{t(`initSetup.${isInit ? 'title' : 'configTitle'}`, { ns: 'appAnnotation' })}
</div>

View File

@ -5,12 +5,12 @@ import { produce } from 'immer'
import * as React from 'react'
import { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import { useFeatures, useFeaturesStore } from '@/app/components/base/features/hooks'
import ConfigParamModal from '@/app/components/base/features/new-feature-panel/annotation-reply/config-param-modal'
import useAnnotationConfig from '@/app/components/base/features/new-feature-panel/annotation-reply/use-annotation-config'
import FeatureCard from '@/app/components/base/features/new-feature-panel/feature-card'
import { MessageFast } from '@/app/components/base/icons/src/vender/features'
import { Button } from '@/app/components/base/ui/button'
import AnnotationFullModal from '@/app/components/billing/annotation-full/modal'
import { ANNOTATION_DEFAULT } from '@/config'
import { usePathname, useRouter } from '@/next/navigation'
@ -92,20 +92,20 @@ const AnnotationReply = ({
>
<>
{!annotationReply?.enabled && (
<div className="line-clamp-2 min-h-8 text-text-tertiary system-xs-regular">{t('feature.annotation.description', { ns: 'appDebug' })}</div>
<div className="line-clamp-2 min-h-8 system-xs-regular text-text-tertiary">{t('feature.annotation.description', { ns: 'appDebug' })}</div>
)}
{!!annotationReply?.enabled && (
<>
{!isHovering && (
<div className="flex items-center gap-4 pt-0.5">
<div className="">
<div className="mb-0.5 text-text-tertiary system-2xs-medium-uppercase">{t('feature.annotation.scoreThreshold.title', { ns: 'appDebug' })}</div>
<div className="text-text-secondary system-xs-regular">{annotationReply.score_threshold || '-'}</div>
<div className="mb-0.5 system-2xs-medium-uppercase text-text-tertiary">{t('feature.annotation.scoreThreshold.title', { ns: 'appDebug' })}</div>
<div className="system-xs-regular text-text-secondary">{annotationReply.score_threshold || '-'}</div>
</div>
<div className="h-[27px] w-px rotate-12 bg-divider-subtle"></div>
<div className="">
<div className="mb-0.5 text-text-tertiary system-2xs-medium-uppercase">{t('modelProvider.embeddingModel.key', { ns: 'common' })}</div>
<div className="text-text-secondary system-xs-regular">{annotationReply.embedding_model?.embedding_model_name}</div>
<div className="mb-0.5 system-2xs-medium-uppercase text-text-tertiary">{t('modelProvider.embeddingModel.key', { ns: 'common' })}</div>
<div className="system-xs-regular text-text-secondary">{annotationReply.embedding_model?.embedding_model_name}</div>
</div>
</div>
)}

View File

@ -6,11 +6,11 @@ import { produce } from 'immer'
import * as React from 'react'
import { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import { useFeatures, useFeaturesStore } from '@/app/components/base/features/hooks'
import FeatureCard from '@/app/components/base/features/new-feature-panel/feature-card'
import { FeatureEnum } from '@/app/components/base/features/types'
import { LoveMessage } from '@/app/components/base/icons/src/vender/features'
import { Button } from '@/app/components/base/ui/button'
import { useModalContext } from '@/context/modal-context'
type Props = {
@ -96,12 +96,12 @@ const ConversationOpener = ({
>
<>
{!opening?.enabled && (
<div className="line-clamp-2 min-h-8 text-text-tertiary system-xs-regular">{t('feature.conversationOpener.description', { ns: 'appDebug' })}</div>
<div className="line-clamp-2 min-h-8 system-xs-regular text-text-tertiary">{t('feature.conversationOpener.description', { ns: 'appDebug' })}</div>
)}
{!!opening?.enabled && (
<>
{!isHovering && (
<div className="line-clamp-2 min-h-8 text-text-tertiary system-xs-regular">
<div className="line-clamp-2 min-h-8 system-xs-regular text-text-tertiary">
{opening.opening_statement || t('openingStatement.placeholder', { ns: 'appDebug' })}
</div>
)}

View File

@ -10,10 +10,10 @@ import { useTranslation } from 'react-i18next'
import { ReactSortable } from 'react-sortablejs'
import ConfirmAddVar from '@/app/components/app/configuration/config-prompt/confirm-add-var'
import { getInputKeys } from '@/app/components/base/block-input'
import Button from '@/app/components/base/button'
import Divider from '@/app/components/base/divider'
import Modal from '@/app/components/base/modal'
import PromptEditor from '@/app/components/base/prompt-editor'
import { Button } from '@/app/components/base/ui/button'
import { cn } from '@/utils/classnames'
import { checkKeys, getNewVar } from '@/utils/var'
@ -104,7 +104,7 @@ const OpeningSettingModal = ({
return (
<div>
<div className="flex items-center py-2">
<div className="flex shrink-0 space-x-0.5 text-xs font-medium leading-[18px] text-text-tertiary">
<div className="flex shrink-0 space-x-0.5 text-xs leading-[18px] font-medium text-text-tertiary">
<div className="uppercase">{t('openingStatement.openingQuestion', { ns: 'appDebug' })}</div>
<div>·</div>
<div>
@ -152,13 +152,13 @@ const OpeningSettingModal = ({
return item
}))
}}
className="h-9 w-full grow cursor-pointer overflow-x-auto rounded-lg border-0 bg-transparent pl-1.5 pr-8 text-sm leading-9 text-text-secondary focus:outline-hidden"
className="h-9 w-full grow cursor-pointer overflow-x-auto rounded-lg border-0 bg-transparent pr-8 pl-1.5 text-sm leading-9 text-text-secondary focus:outline-hidden"
onFocus={() => setFocusID(index)}
onBlur={() => setFocusID(null)}
/>
<div
className="absolute right-1.5 top-1/2 block translate-y-[-50%] cursor-pointer rounded-md p-1 text-text-tertiary hover:bg-state-destructive-hover hover:text-text-destructive"
className="absolute top-1/2 right-1.5 block translate-y-[-50%] cursor-pointer rounded-md p-1 text-text-tertiary hover:bg-state-destructive-hover hover:text-text-destructive"
onClick={() => {
setTempSuggestedQuestions(tempSuggestedQuestions.filter((_, i) => index !== i))
}}
@ -177,7 +177,7 @@ const OpeningSettingModal = ({
className="mt-1 flex h-9 cursor-pointer items-center gap-2 rounded-lg bg-components-button-tertiary-bg px-3 text-components-button-tertiary-text hover:bg-components-button-tertiary-bg-hover"
>
<span className="i-ri-add-line h-4 w-4" />
<div className="text-[13px] system-sm-medium">{t('variableConfig.addOption', { ns: 'appDebug' })}</div>
<div className="system-sm-medium text-[13px]">{t('variableConfig.addOption', { ns: 'appDebug' })}</div>
</div>
)}
</div>
@ -191,7 +191,7 @@ const OpeningSettingModal = ({
className="mt-14! w-[640px]! max-w-none! bg-components-panel-bg-blur! p-6!"
>
<div className="mb-6 flex items-center justify-between">
<div className="text-text-primary title-2xl-semi-bold">{t('feature.conversationOpener.title', { ns: 'appDebug' })}</div>
<div className="title-2xl-semi-bold text-text-primary">{t('feature.conversationOpener.title', { ns: 'appDebug' })}</div>
<div
className="cursor-pointer p-1"
onClick={onCancel}

Some files were not shown because too many files have changed in this diff Show More