mirror of
https://github.com/langgenius/dify.git
synced 2026-03-14 11:47:05 +00:00
Compare commits
269 Commits
internal-f
...
deploy/dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bdbec77c54 | ||
|
|
471106cef1 | ||
|
|
b70c78446d | ||
|
|
0c42c11d28 | ||
|
|
03c58d151a | ||
|
|
fcc8e79733 | ||
|
|
21cb5ae1b6 | ||
|
|
7a308c9f40 | ||
|
|
a985be6282 | ||
|
|
92eb6de4de | ||
|
|
d0054e28fe | ||
|
|
33626cb3e1 | ||
|
|
11aca07375 | ||
|
|
ab71798546 | ||
|
|
a1410dc531 | ||
|
|
e2f433bab9 | ||
|
|
64a66f2adc | ||
|
|
e407d688d2 | ||
|
|
2f85c77a54 | ||
|
|
906852fbd6 | ||
|
|
729e18a7d6 | ||
|
|
4ed49f1d98 | ||
|
|
9633199ccf | ||
|
|
04f4627f9b | ||
|
|
c167ee199c | ||
|
|
3772447716 | ||
|
|
339a8ca057 | ||
|
|
d39f243a4a | ||
|
|
911d52cafc | ||
|
|
fee6d13f44 | ||
|
|
cb8e20786a | ||
|
|
d27a737cd1 | ||
|
|
9dceca129e | ||
|
|
167fcc866d | ||
|
|
38afc84f0f | ||
|
|
acef4a40b0 | ||
|
|
1f5ef43f8c | ||
|
|
82ad93eb1a | ||
|
|
c3664540f2 | ||
|
|
f0086888e3 | ||
|
|
ee2280851d | ||
|
|
e9d0c7bb2a | ||
|
|
06e1d59e1d | ||
|
|
bd2bb27faa | ||
|
|
c08b9a289b | ||
|
|
715a0fabfc | ||
|
|
5d07ccce59 | ||
|
|
45e4d47207 | ||
|
|
68bddc9637 | ||
|
|
fa664ebe77 | ||
|
|
a22d00c420 | ||
|
|
563d0c6892 | ||
|
|
05bf2c15e1 | ||
|
|
af2a6b2de0 | ||
|
|
421f6f2ad5 | ||
|
|
908e57b9f5 | ||
|
|
d72fbce31c | ||
|
|
6cb68b6de5 | ||
|
|
aeaf6d2ce9 | ||
|
|
ad4cb51983 | ||
|
|
3f27c8a9d2 | ||
|
|
c2def7a840 | ||
|
|
1e6bcb1e49 | ||
|
|
419e46ae49 | ||
|
|
f18fd566ba | ||
|
|
0acc2eaa00 | ||
|
|
e0947a1ea8 | ||
|
|
e51162af0c | ||
|
|
358407bbe0 | ||
|
|
08da390678 | ||
|
|
250450a54e | ||
|
|
5709a34a7f | ||
|
|
275e6ebbd8 | ||
|
|
d35bbf0fc5 | ||
|
|
6071d019e1 | ||
|
|
dd284270af | ||
|
|
a9a9f41245 | ||
|
|
bd7ffca12c | ||
|
|
cc35e92258 | ||
|
|
862a907d02 | ||
|
|
0128c609eb | ||
|
|
4235071f61 | ||
|
|
0da50e4f18 | ||
|
|
d1177e90aa | ||
|
|
e8ade9ad64 | ||
|
|
34a5645d94 | ||
|
|
5e80a3f5de | ||
|
|
7e25eaa32e | ||
|
|
785e04816e | ||
|
|
990f839f39 | ||
|
|
2704688f59 | ||
|
|
7699b0d430 | ||
|
|
0ff8539c97 | ||
|
|
45c96dc254 | ||
|
|
3a957cc28b | ||
|
|
c1765a3725 | ||
|
|
705e4427bd | ||
|
|
a8fa3ff3cf | ||
|
|
e33a210df1 | ||
|
|
7ed7562be6 | ||
|
|
fda5d12107 | ||
|
|
17043ed2c9 | ||
|
|
0b2ded3227 | ||
|
|
369e4eb7b0 | ||
|
|
5ddd749c9e | ||
|
|
55a80bda5d | ||
|
|
2ed07abed2 | ||
|
|
37d286e844 | ||
|
|
a4942139d2 | ||
|
|
83c15227f6 | ||
|
|
c3c678a328 | ||
|
|
60f86f0520 | ||
|
|
ba771d9930 | ||
|
|
b3c98e417d | ||
|
|
9f0436be92 | ||
|
|
c45602ee78 | ||
|
|
dfe389c017 | ||
|
|
1fa9314482 | ||
|
|
b364b06e51 | ||
|
|
ce0197b107 | ||
|
|
4e3853a75e | ||
|
|
cb35e54d79 | ||
|
|
65b2e8c525 | ||
|
|
164cefc65c | ||
|
|
9e7aeb36ca | ||
|
|
f6d80b9fa7 | ||
|
|
e845fa7e6a | ||
|
|
bab7bd5ecc | ||
|
|
cfb02bceaf | ||
|
|
694ca840e1 | ||
|
|
2d979e2cec | ||
|
|
5cee7cf8ce | ||
|
|
2af2359d30 | ||
|
|
0c17823c8b | ||
|
|
49c6696d08 | ||
|
|
292c98a8f3 | ||
|
|
f1949f2f54 | ||
|
|
bc0f01228c | ||
|
|
0e0a6ad043 | ||
|
|
f51a91eb70 | ||
|
|
456c95adb1 | ||
|
|
1abbaf9fd5 | ||
|
|
1a26e1669b | ||
|
|
02444af2e3 | ||
|
|
56038e3684 | ||
|
|
eb9341e7ec | ||
|
|
e40b31b9c4 | ||
|
|
b89ee4807f | ||
|
|
89b1195aa9 | ||
|
|
1f2bf7a42b | ||
|
|
ce720b331a | ||
|
|
7ccdc30133 | ||
|
|
8c0875322e | ||
|
|
9907cf9e06 | ||
|
|
208a31719f | ||
|
|
3d1ef1f7f5 | ||
|
|
24b14e2c1a | ||
|
|
53f122f717 | ||
|
|
fced2f9e65 | ||
|
|
0c08c4016d | ||
|
|
ff4e4a8d64 | ||
|
|
948efa129f | ||
|
|
e371bfd676 | ||
|
|
6d612c0909 | ||
|
|
56e0dc0ae6 | ||
|
|
286ac42b2e | ||
|
|
975eca00c3 | ||
|
|
f049bafcc3 | ||
|
|
42d08995bc | ||
|
|
8e3a8ef908 | ||
|
|
10bb786341 | ||
|
|
2b7370b4cd | ||
|
|
145276d716 | ||
|
|
39701488ba | ||
|
|
dd9c526447 | ||
|
|
fa99aef0c8 | ||
|
|
a6cc31f48e | ||
|
|
922dc71e36 | ||
|
|
f03ec7f671 | ||
|
|
29f275442d | ||
|
|
c9532ffd43 | ||
|
|
8c6fd6d3a2 | ||
|
|
8ad5cb5c85 | ||
|
|
840dc33b8b | ||
|
|
aa4cae3339 | ||
|
|
cae58a0649 | ||
|
|
1752edc047 | ||
|
|
00a79a3e26 | ||
|
|
7471c32612 | ||
|
|
88d87d6053 | ||
|
|
59f826570d | ||
|
|
2d333bbbe5 | ||
|
|
4af6788ce0 | ||
|
|
24b072def9 | ||
|
|
909c8c3350 | ||
|
|
80e9c8bee0 | ||
|
|
15b7b304d2 | ||
|
|
61e2672b59 | ||
|
|
5f4ed4c6f6 | ||
|
|
4a1032c628 | ||
|
|
423c97a47e | ||
|
|
a7e3fb2e33 | ||
|
|
ce34937a1c | ||
|
|
ad9ac6978e | ||
|
|
e2b247d762 | ||
|
|
57c1ba3543 | ||
|
|
37b15acd0d | ||
|
|
d7a5af2b9a | ||
|
|
0ce9ebed63 | ||
|
|
d45edffaa3 | ||
|
|
530515b6ef | ||
|
|
1fa68d0863 | ||
|
|
f13f0d1f9a | ||
|
|
b597d52c11 | ||
|
|
34c42fe666 | ||
|
|
dc109c99f0 | ||
|
|
4a0770192e | ||
|
|
223b9d89c1 | ||
|
|
dd119eb44f | ||
|
|
970493fa85 | ||
|
|
ab87ac333a | ||
|
|
b8b70da9ad | ||
|
|
26d96f97a7 | ||
|
|
77d81aebe8 | ||
|
|
deb4cd3ece | ||
|
|
648d9ef1f9 | ||
|
|
5ed4797078 | ||
|
|
62631658e9 | ||
|
|
22a4100dd7 | ||
|
|
0f7ed6f67e | ||
|
|
4d9fcbec57 | ||
|
|
4d7a9bc798 | ||
|
|
d6d04ed657 | ||
|
|
f594a71dae | ||
|
|
04e0ab7eda | ||
|
|
784bda9c86 | ||
|
|
1af1fb6913 | ||
|
|
1f0c36e9f7 | ||
|
|
455ae65025 | ||
|
|
d44682e957 | ||
|
|
8c4afc0c18 | ||
|
|
539cbcae6a | ||
|
|
8d257fea7c | ||
|
|
c3364ac350 | ||
|
|
f991644989 | ||
|
|
29e344ac8b | ||
|
|
1ad9305732 | ||
|
|
17f38f171d | ||
|
|
802088c8eb | ||
|
|
cad6d94491 | ||
|
|
621d0fb2c9 | ||
|
|
efdd88f78a | ||
|
|
a92fb3244b | ||
|
|
97508f8d7b | ||
|
|
908820acb4 | ||
|
|
b2f84bf081 | ||
|
|
70e677a6ac | ||
|
|
6f890496fa | ||
|
|
6f6b3cf841 | ||
|
|
2330aac623 | ||
|
|
97769c5c7a | ||
|
|
09ae3a9b52 | ||
|
|
9589bba713 | ||
|
|
6473c1419b | ||
|
|
d1a0b9695c | ||
|
|
3147e44a0b | ||
|
|
c243e91668 | ||
|
|
004fbbe52b | ||
|
|
63fb0ddde5 |
4
.github/workflows/web-tests.yml
vendored
4
.github/workflows/web-tests.yml
vendored
@@ -26,8 +26,8 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
shardIndex: [1, 2, 3, 4]
|
||||
shardTotal: [4]
|
||||
shardIndex: [1, 2, 3, 4, 5, 6]
|
||||
shardTotal: [6]
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
@@ -295,24 +295,7 @@ describe('Pricing Modal Flow', () => {
|
||||
})
|
||||
})
|
||||
|
||||
// ─── 6. Close Handling ───────────────────────────────────────────────────
|
||||
describe('Close handling', () => {
|
||||
it('should call onCancel when pressing ESC key', () => {
|
||||
render(<Pricing onCancel={onCancel} />)
|
||||
|
||||
// ahooks useKeyPress listens on document for keydown events
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', {
|
||||
key: 'Escape',
|
||||
code: 'Escape',
|
||||
keyCode: 27,
|
||||
bubbles: true,
|
||||
}))
|
||||
|
||||
expect(onCancel).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
|
||||
// ─── 7. Pricing URL ─────────────────────────────────────────────────────
|
||||
// ─── 6. Pricing URL ─────────────────────────────────────────────────────
|
||||
describe('Pricing page URL', () => {
|
||||
it('should render pricing link with correct URL', () => {
|
||||
render(<Pricing onCancel={onCancel} />)
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
import { cleanup, render, screen } from '@testing-library/react'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
let mockTheme = 'light'
|
||||
|
||||
vi.mock('#i18n', () => ({
|
||||
useTranslation: () => ({
|
||||
t: (key: string) => key,
|
||||
@@ -19,16 +21,16 @@ vi.mock('@/context/i18n', () => ({
|
||||
}))
|
||||
|
||||
vi.mock('@/hooks/use-theme', () => ({
|
||||
default: () => ({ theme: 'light' }),
|
||||
default: () => ({ theme: mockTheme }),
|
||||
}))
|
||||
|
||||
vi.mock('@/i18n-config', () => ({
|
||||
renderI18nObject: (obj: Record<string, string>, locale: string) => obj[locale] || obj.en_US || '',
|
||||
}))
|
||||
|
||||
vi.mock('@/types/app', () => ({
|
||||
Theme: { dark: 'dark', light: 'light' },
|
||||
}))
|
||||
vi.mock('@/types/app', async () => {
|
||||
return vi.importActual<typeof import('@/types/app')>('@/types/app')
|
||||
})
|
||||
|
||||
vi.mock('@/utils/classnames', () => ({
|
||||
cn: (...args: unknown[]) => args.filter(a => typeof a === 'string' && a).join(' '),
|
||||
@@ -100,6 +102,7 @@ type CardPayload = Parameters<typeof Card>[0]['payload']
|
||||
describe('Plugin Card Rendering Integration', () => {
|
||||
beforeEach(() => {
|
||||
cleanup()
|
||||
mockTheme = 'light'
|
||||
})
|
||||
|
||||
const makePayload = (overrides = {}) => ({
|
||||
@@ -194,9 +197,7 @@ describe('Plugin Card Rendering Integration', () => {
|
||||
})
|
||||
|
||||
it('uses dark icon when theme is dark and icon_dark is provided', () => {
|
||||
vi.doMock('@/hooks/use-theme', () => ({
|
||||
default: () => ({ theme: 'dark' }),
|
||||
}))
|
||||
mockTheme = 'dark'
|
||||
|
||||
const payload = makePayload({
|
||||
icon: 'https://example.com/icon-light.png',
|
||||
@@ -204,7 +205,7 @@ describe('Plugin Card Rendering Integration', () => {
|
||||
})
|
||||
|
||||
render(<Card payload={payload} />)
|
||||
expect(screen.getByTestId('card-icon')).toBeInTheDocument()
|
||||
expect(screen.getByTestId('card-icon')).toHaveTextContent('https://example.com/icon-dark.png')
|
||||
})
|
||||
|
||||
it('shows loading placeholder when isLoading is true', () => {
|
||||
|
||||
@@ -48,7 +48,7 @@ export default function ChartView({ appId, headerRight }: IChartViewProps) {
|
||||
return (
|
||||
<div>
|
||||
<div className="mb-4">
|
||||
<div className="system-xl-semibold mb-2 text-text-primary">{t('appMenus.overview', { ns: 'common' })}</div>
|
||||
<div className="mb-2 text-text-primary system-xl-semibold">{t('appMenus.overview', { ns: 'common' })}</div>
|
||||
<div className="flex items-center justify-between">
|
||||
{IS_CLOUD_EDITION
|
||||
? (
|
||||
|
||||
@@ -30,7 +30,7 @@ const DatePicker: FC<Props> = ({
|
||||
|
||||
const renderDate = useCallback(({ value, handleClickTrigger, isOpen }: TriggerProps) => {
|
||||
return (
|
||||
<div className={cn('system-sm-regular flex h-7 cursor-pointer items-center rounded-lg px-1 text-components-input-text-filled hover:bg-state-base-hover', isOpen && 'bg-state-base-hover')} onClick={handleClickTrigger}>
|
||||
<div className={cn('flex h-7 cursor-pointer items-center rounded-lg px-1 text-components-input-text-filled system-sm-regular hover:bg-state-base-hover', isOpen && 'bg-state-base-hover')} onClick={handleClickTrigger}>
|
||||
{value ? formatToLocalTime(value, locale, 'MMM D') : ''}
|
||||
</div>
|
||||
)
|
||||
@@ -64,7 +64,7 @@ const DatePicker: FC<Props> = ({
|
||||
noConfirm
|
||||
getIsDateDisabled={startDateDisabled}
|
||||
/>
|
||||
<span className="system-sm-regular text-text-tertiary">-</span>
|
||||
<span className="text-text-tertiary system-sm-regular">-</span>
|
||||
<Picker
|
||||
value={end}
|
||||
onChange={onEndChange}
|
||||
|
||||
@@ -45,7 +45,7 @@ const RangeSelector: FC<Props> = ({
|
||||
const renderTrigger = useCallback((item: Item | null, isOpen: boolean) => {
|
||||
return (
|
||||
<div className={cn('flex h-8 cursor-pointer items-center space-x-1.5 rounded-lg bg-components-input-bg-normal pl-3 pr-2', isOpen && 'bg-state-base-hover-alt')}>
|
||||
<div className="system-sm-regular text-components-input-text-filled">{isCustomRange ? t('filter.period.custom', { ns: 'appLog' }) : item?.name}</div>
|
||||
<div className="text-components-input-text-filled system-sm-regular">{isCustomRange ? t('filter.period.custom', { ns: 'appLog' }) : item?.name}</div>
|
||||
<RiArrowDownSLine className={cn('size-4 text-text-quaternary', isOpen && 'text-text-secondary')} />
|
||||
</div>
|
||||
)
|
||||
@@ -57,13 +57,13 @@ const RangeSelector: FC<Props> = ({
|
||||
{selected && (
|
||||
<span
|
||||
className={cn(
|
||||
'absolute left-2 top-[9px] flex items-center text-text-accent',
|
||||
'absolute left-2 top-[9px] flex items-center text-text-accent',
|
||||
)}
|
||||
>
|
||||
<RiCheckLine className="h-4 w-4" aria-hidden="true" />
|
||||
</span>
|
||||
)}
|
||||
<span className={cn('system-md-regular block truncate')}>{item.name}</span>
|
||||
<span className={cn('block truncate system-md-regular')}>{item.name}</span>
|
||||
</>
|
||||
)
|
||||
}, [])
|
||||
|
||||
@@ -327,11 +327,11 @@ const ConfigPopup: FC<PopupProps> = ({
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
<TracingIcon size="md" className="mr-2" />
|
||||
<div className="title-2xl-semi-bold text-text-primary">{t(`${I18N_PREFIX}.tracing`, { ns: 'app' })}</div>
|
||||
<div className="text-text-primary title-2xl-semi-bold">{t(`${I18N_PREFIX}.tracing`, { ns: 'app' })}</div>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<Indicator color={enabled ? 'green' : 'gray'} />
|
||||
<div className={cn('system-xs-semibold-uppercase ml-1 text-text-tertiary', enabled && 'text-util-colors-green-green-600')}>
|
||||
<div className={cn('ml-1 text-text-tertiary system-xs-semibold-uppercase', enabled && 'text-util-colors-green-green-600')}>
|
||||
{t(`${I18N_PREFIX}.${enabled ? 'enabled' : 'disabled'}`, { ns: 'app' })}
|
||||
</div>
|
||||
{!readOnly && (
|
||||
@@ -350,7 +350,7 @@ const ConfigPopup: FC<PopupProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="system-xs-regular mt-2 text-text-tertiary">
|
||||
<div className="mt-2 text-text-tertiary system-xs-regular">
|
||||
{t(`${I18N_PREFIX}.tracingDescription`, { ns: 'app' })}
|
||||
</div>
|
||||
<Divider className="my-3" />
|
||||
@@ -358,7 +358,7 @@ const ConfigPopup: FC<PopupProps> = ({
|
||||
{(providerAllConfigured || providerAllNotConfigured)
|
||||
? (
|
||||
<>
|
||||
<div className="system-xs-medium-uppercase text-text-tertiary">{t(`${I18N_PREFIX}.configProviderTitle.${providerAllConfigured ? 'configured' : 'notConfigured'}`, { ns: 'app' })}</div>
|
||||
<div className="text-text-tertiary system-xs-medium-uppercase">{t(`${I18N_PREFIX}.configProviderTitle.${providerAllConfigured ? 'configured' : 'notConfigured'}`, { ns: 'app' })}</div>
|
||||
<div className="mt-2 max-h-96 space-y-2 overflow-y-auto">
|
||||
{langfusePanel}
|
||||
{langSmithPanel}
|
||||
@@ -375,11 +375,11 @@ const ConfigPopup: FC<PopupProps> = ({
|
||||
)
|
||||
: (
|
||||
<>
|
||||
<div className="system-xs-medium-uppercase text-text-tertiary">{t(`${I18N_PREFIX}.configProviderTitle.configured`, { ns: 'app' })}</div>
|
||||
<div className="text-text-tertiary system-xs-medium-uppercase">{t(`${I18N_PREFIX}.configProviderTitle.configured`, { ns: 'app' })}</div>
|
||||
<div className="mt-2 max-h-40 space-y-2 overflow-y-auto">
|
||||
{configuredProviderPanel()}
|
||||
</div>
|
||||
<div className="system-xs-medium-uppercase mt-3 text-text-tertiary">{t(`${I18N_PREFIX}.configProviderTitle.moreProvider`, { ns: 'app' })}</div>
|
||||
<div className="mt-3 text-text-tertiary system-xs-medium-uppercase">{t(`${I18N_PREFIX}.configProviderTitle.moreProvider`, { ns: 'app' })}</div>
|
||||
<div className="mt-2 max-h-40 space-y-2 overflow-y-auto">
|
||||
{moreProviderPanel()}
|
||||
</div>
|
||||
|
||||
@@ -254,7 +254,7 @@ const Panel: FC = () => {
|
||||
)}
|
||||
>
|
||||
<TracingIcon size="md" />
|
||||
<div className="system-sm-semibold mx-2 text-text-secondary">{t(`${I18N_PREFIX}.title`, { ns: 'app' })}</div>
|
||||
<div className="mx-2 text-text-secondary system-sm-semibold">{t(`${I18N_PREFIX}.title`, { ns: 'app' })}</div>
|
||||
<div className="rounded-md p-1">
|
||||
<RiEqualizer2Line className="h-4 w-4 text-text-tertiary" />
|
||||
</div>
|
||||
@@ -294,7 +294,7 @@ const Panel: FC = () => {
|
||||
>
|
||||
<div className="ml-4 mr-1 flex items-center">
|
||||
<Indicator color={enabled ? 'green' : 'gray'} />
|
||||
<div className="system-xs-semibold-uppercase ml-1.5 text-text-tertiary">
|
||||
<div className="ml-1.5 text-text-tertiary system-xs-semibold-uppercase">
|
||||
{t(`${I18N_PREFIX}.${enabled ? 'enabled' : 'disabled'}`, { ns: 'app' })}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -302,7 +302,7 @@ const ProviderConfigModal: FC<Props> = ({
|
||||
<div className="mx-2 max-h-[calc(100vh-120px)] w-[640px] overflow-y-auto rounded-2xl bg-components-panel-bg shadow-xl">
|
||||
<div className="px-8 pt-8">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<div className="title-2xl-semi-bold text-text-primary">
|
||||
<div className="text-text-primary title-2xl-semi-bold">
|
||||
{t(`${I18N_PREFIX}.title`, { ns: 'app' })}
|
||||
{t(`tracing.${type}.title`, { ns: 'app' })}
|
||||
</div>
|
||||
|
||||
@@ -82,7 +82,7 @@ const ProviderPanel: FC<Props> = ({
|
||||
<div className="flex items-center justify-between space-x-1">
|
||||
<div className="flex items-center">
|
||||
<Icon className="h-6" />
|
||||
{isChosen && <div className="system-2xs-medium-uppercase ml-1 flex h-4 items-center rounded-[4px] border border-text-accent-secondary px-1 text-text-accent-secondary">{t(`${I18N_PREFIX}.inUse`, { ns: 'app' })}</div>}
|
||||
{isChosen && <div className="ml-1 flex h-4 items-center rounded-[4px] border border-text-accent-secondary px-1 text-text-accent-secondary system-2xs-medium-uppercase">{t(`${I18N_PREFIX}.inUse`, { ns: 'app' })}</div>}
|
||||
</div>
|
||||
{!readOnly && (
|
||||
<div className="flex items-center justify-between space-x-1">
|
||||
@@ -102,7 +102,7 @@ const ProviderPanel: FC<Props> = ({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="system-xs-regular mt-2 text-text-tertiary">
|
||||
<div className="mt-2 text-text-tertiary system-xs-regular">
|
||||
{t(`${I18N_PREFIX}.${type}.description`, { ns: 'app' })}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,8 +7,8 @@ const Settings = () => {
|
||||
return (
|
||||
<div className="h-full overflow-y-auto">
|
||||
<div className="flex flex-col gap-y-0.5 px-6 pb-2 pt-3">
|
||||
<div className="system-xl-semibold text-text-primary">{t('title')}</div>
|
||||
<div className="system-sm-regular text-text-tertiary">{t('desc')}</div>
|
||||
<div className="text-text-primary system-xl-semibold">{t('title')}</div>
|
||||
<div className="text-text-tertiary system-sm-regular">{t('desc')}</div>
|
||||
</div>
|
||||
<Form />
|
||||
</div>
|
||||
|
||||
@@ -106,17 +106,17 @@ const FormContent = () => {
|
||||
<RiCheckboxCircleFill className="h-8 w-8 text-text-success" />
|
||||
</div>
|
||||
<div className="grow">
|
||||
<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 className="text-text-primary title-4xl-semi-bold">{t('humanInput.thanks', { ns: 'share' })}</div>
|
||||
<div className="text-text-primary title-4xl-semi-bold">{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 text-text-tertiary system-2xs-regular-uppercase">{t('humanInput.submissionID', { id: token, ns: 'share' })}</div>
|
||||
</div>
|
||||
<div className="flex flex-row-reverse px-2 py-3">
|
||||
<div className={cn(
|
||||
'flex shrink-0 items-center gap-1.5 px-1',
|
||||
)}
|
||||
>
|
||||
<div className="system-2xs-medium-uppercase text-text-tertiary">{t('chat.poweredBy', { ns: 'share' })}</div>
|
||||
<div className="text-text-tertiary system-2xs-medium-uppercase">{t('chat.poweredBy', { ns: 'share' })}</div>
|
||||
<DifyLogo size="small" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -134,17 +134,17 @@ const FormContent = () => {
|
||||
<RiInformation2Fill className="h-8 w-8 text-text-accent" />
|
||||
</div>
|
||||
<div className="grow">
|
||||
<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 className="text-text-primary title-4xl-semi-bold">{t('humanInput.sorry', { ns: 'share' })}</div>
|
||||
<div className="text-text-primary title-4xl-semi-bold">{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 text-text-tertiary system-2xs-regular-uppercase">{t('humanInput.submissionID', { id: token, ns: 'share' })}</div>
|
||||
</div>
|
||||
<div className="flex flex-row-reverse px-2 py-3">
|
||||
<div className={cn(
|
||||
'flex shrink-0 items-center gap-1.5 px-1',
|
||||
)}
|
||||
>
|
||||
<div className="system-2xs-medium-uppercase text-text-tertiary">{t('chat.poweredBy', { ns: 'share' })}</div>
|
||||
<div className="text-text-tertiary system-2xs-medium-uppercase">{t('chat.poweredBy', { ns: 'share' })}</div>
|
||||
<DifyLogo size="small" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -162,17 +162,17 @@ const FormContent = () => {
|
||||
<RiInformation2Fill className="h-8 w-8 text-text-accent" />
|
||||
</div>
|
||||
<div className="grow">
|
||||
<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 className="text-text-primary title-4xl-semi-bold">{t('humanInput.sorry', { ns: 'share' })}</div>
|
||||
<div className="text-text-primary title-4xl-semi-bold">{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 text-text-tertiary system-2xs-regular-uppercase">{t('humanInput.submissionID', { id: token, ns: 'share' })}</div>
|
||||
</div>
|
||||
<div className="flex flex-row-reverse px-2 py-3">
|
||||
<div className={cn(
|
||||
'flex shrink-0 items-center gap-1.5 px-1',
|
||||
)}
|
||||
>
|
||||
<div className="system-2xs-medium-uppercase text-text-tertiary">{t('chat.poweredBy', { ns: 'share' })}</div>
|
||||
<div className="text-text-tertiary system-2xs-medium-uppercase">{t('chat.poweredBy', { ns: 'share' })}</div>
|
||||
<DifyLogo size="small" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -190,7 +190,7 @@ const FormContent = () => {
|
||||
<RiErrorWarningFill className="h-8 w-8 text-text-destructive" />
|
||||
</div>
|
||||
<div className="grow">
|
||||
<div className="title-4xl-semi-bold text-text-primary">{t('humanInput.rateLimitExceeded', { ns: 'share' })}</div>
|
||||
<div className="text-text-primary title-4xl-semi-bold">{t('humanInput.rateLimitExceeded', { ns: 'share' })}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row-reverse px-2 py-3">
|
||||
@@ -198,7 +198,7 @@ const FormContent = () => {
|
||||
'flex shrink-0 items-center gap-1.5 px-1',
|
||||
)}
|
||||
>
|
||||
<div className="system-2xs-medium-uppercase text-text-tertiary">{t('chat.poweredBy', { ns: 'share' })}</div>
|
||||
<div className="text-text-tertiary system-2xs-medium-uppercase">{t('chat.poweredBy', { ns: 'share' })}</div>
|
||||
<DifyLogo size="small" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -216,7 +216,7 @@ const FormContent = () => {
|
||||
<RiErrorWarningFill className="h-8 w-8 text-text-destructive" />
|
||||
</div>
|
||||
<div className="grow">
|
||||
<div className="title-4xl-semi-bold text-text-primary">{t('humanInput.formNotFound', { ns: 'share' })}</div>
|
||||
<div className="text-text-primary title-4xl-semi-bold">{t('humanInput.formNotFound', { ns: 'share' })}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row-reverse px-2 py-3">
|
||||
@@ -224,7 +224,7 @@ const FormContent = () => {
|
||||
'flex shrink-0 items-center gap-1.5 px-1',
|
||||
)}
|
||||
>
|
||||
<div className="system-2xs-medium-uppercase text-text-tertiary">{t('chat.poweredBy', { ns: 'share' })}</div>
|
||||
<div className="text-text-tertiary system-2xs-medium-uppercase">{t('chat.poweredBy', { ns: 'share' })}</div>
|
||||
<DifyLogo size="small" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -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 text-text-primary system-xl-semibold">{site.title}</div>
|
||||
</div>
|
||||
<div className="h-0 w-full grow overflow-y-auto">
|
||||
<div className="border-components-divider-subtle rounded-[20px] border bg-chat-bubble-bg p-4 shadow-lg backdrop-blur-sm">
|
||||
@@ -277,7 +277,7 @@ const FormContent = () => {
|
||||
'flex shrink-0 items-center gap-1.5 px-1',
|
||||
)}
|
||||
>
|
||||
<div className="system-2xs-medium-uppercase text-text-tertiary">{t('chat.poweredBy', { ns: 'share' })}</div>
|
||||
<div className="text-text-tertiary system-2xs-medium-uppercase">{t('chat.poweredBy', { ns: 'share' })}</div>
|
||||
<DifyLogo size="small" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -81,7 +81,7 @@ const AuthenticatedLayout = ({ children }: { children: React.ReactNode }) => {
|
||||
return (
|
||||
<div className="flex h-full flex-col items-center justify-center gap-y-2">
|
||||
<AppUnavailable className="h-auto w-auto" code={403} unknownReason="no permission." />
|
||||
<span className="system-sm-regular cursor-pointer text-text-tertiary" onClick={backToHome}>{t('userProfile.logout', { ns: 'common' })}</span>
|
||||
<span className="cursor-pointer text-text-tertiary system-sm-regular" onClick={backToHome}>{t('userProfile.logout', { ns: 'common' })}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ const Splash: FC<PropsWithChildren> = ({ children }) => {
|
||||
return (
|
||||
<div className="flex h-full flex-col items-center justify-center gap-y-4">
|
||||
<AppUnavailable className="h-auto w-auto" code={code || t('common.appUnavailable', { ns: 'share' })} unknownReason={message} />
|
||||
<span className="system-sm-regular cursor-pointer text-text-tertiary" onClick={backToHome}>{code === '403' ? t('userProfile.logout', { ns: 'common' }) : t('login.backToHome', { ns: 'share' })}</span>
|
||||
<span className="cursor-pointer text-text-tertiary system-sm-regular" onClick={backToHome}>{code === '403' ? t('userProfile.logout', { ns: 'common' }) : t('login.backToHome', { ns: 'share' })}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -69,8 +69,8 @@ export default function CheckCode() {
|
||||
<RiMailSendFill className="h-6 w-6 text-2xl" />
|
||||
</div>
|
||||
<div className="pb-4 pt-2">
|
||||
<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">
|
||||
<h2 className="text-text-primary title-4xl-semi-bold">{t('checkCode.checkYourEmail', { ns: 'login' })}</h2>
|
||||
<p className="mt-2 text-text-secondary body-md-regular">
|
||||
<span>
|
||||
{t('checkCode.tipsPrefix', { ns: 'login' })}
|
||||
<strong>{email}</strong>
|
||||
@@ -82,7 +82,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 text-text-secondary system-md-semibold">{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} />
|
||||
@@ -94,7 +94,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>
|
||||
)
|
||||
|
||||
@@ -24,7 +24,7 @@ export default function SignInLayout({ children }: any) {
|
||||
</div>
|
||||
</div>
|
||||
{!systemFeatures.branding.enabled && (
|
||||
<div className="system-xs-regular px-8 py-6 text-text-tertiary">
|
||||
<div className="px-8 py-6 text-text-tertiary system-xs-regular">
|
||||
©
|
||||
{' '}
|
||||
{new Date().getFullYear()}
|
||||
|
||||
@@ -74,8 +74,8 @@ export default function CheckCode() {
|
||||
<RiLockPasswordLine className="h-6 w-6 text-2xl text-text-accent-light-mode-only" />
|
||||
</div>
|
||||
<div className="pb-4 pt-2">
|
||||
<h2 className="title-4xl-semi-bold text-text-primary">{t('resetPassword', { ns: 'login' })}</h2>
|
||||
<p className="body-md-regular mt-2 text-text-secondary">
|
||||
<h2 className="text-text-primary title-4xl-semi-bold">{t('resetPassword', { ns: 'login' })}</h2>
|
||||
<p className="mt-2 text-text-secondary body-md-regular">
|
||||
{t('resetPasswordDesc', { ns: 'login' })}
|
||||
</p>
|
||||
</div>
|
||||
@@ -83,7 +83,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 text-text-secondary system-md-semibold">{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>
|
||||
@@ -99,7 +99,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>
|
||||
)
|
||||
|
||||
@@ -91,10 +91,10 @@ const ChangePasswordForm = () => {
|
||||
{!showSuccess && (
|
||||
<div className="flex flex-col md:w-[400px]">
|
||||
<div className="mx-auto w-full">
|
||||
<h2 className="title-4xl-semi-bold text-text-primary">
|
||||
<h2 className="text-text-primary title-4xl-semi-bold">
|
||||
{t('changePassword', { ns: 'login' })}
|
||||
</h2>
|
||||
<p className="body-md-regular mt-2 text-text-secondary">
|
||||
<p className="mt-2 text-text-secondary body-md-regular">
|
||||
{t('changePasswordTip', { ns: 'login' })}
|
||||
</p>
|
||||
</div>
|
||||
@@ -103,7 +103,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 text-text-secondary system-md-semibold">
|
||||
{t('account.newPassword', { ns: 'common' })}
|
||||
</label>
|
||||
<div className="relative mt-1">
|
||||
@@ -125,11 +125,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 text-text-secondary body-xs-regular">{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 text-text-secondary system-md-semibold">
|
||||
{t('account.confirmPassword', { ns: 'common' })}
|
||||
</label>
|
||||
<div className="relative mt-1">
|
||||
@@ -170,7 +170,7 @@ const ChangePasswordForm = () => {
|
||||
<div className="mb-3 flex h-14 w-14 items-center justify-center rounded-2xl border border-components-panel-border-subtle font-bold shadow-lg">
|
||||
<RiCheckboxCircleFill className="h-6 w-6 text-text-success" />
|
||||
</div>
|
||||
<h2 className="title-4xl-semi-bold text-text-primary">
|
||||
<h2 className="text-text-primary title-4xl-semi-bold">
|
||||
{t('passwordChangedTip', { ns: 'login' })}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
@@ -110,8 +110,8 @@ export default function CheckCode() {
|
||||
<RiMailSendFill className="h-6 w-6 text-2xl text-text-accent-light-mode-only" />
|
||||
</div>
|
||||
<div className="pb-4 pt-2">
|
||||
<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">
|
||||
<h2 className="text-text-primary title-4xl-semi-bold">{t('checkCode.checkYourEmail', { ns: 'login' })}</h2>
|
||||
<p className="mt-2 text-text-secondary body-md-regular">
|
||||
<span>
|
||||
{t('checkCode.tipsPrefix', { ns: 'login' })}
|
||||
<strong>{email}</strong>
|
||||
@@ -122,7 +122,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 text-text-secondary system-md-semibold">{t('checkCode.verificationCode', { ns: 'login' })}</label>
|
||||
<Input
|
||||
ref={codeInputRef}
|
||||
id="code"
|
||||
@@ -142,7 +142,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>
|
||||
)
|
||||
|
||||
@@ -55,7 +55,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 text-text-secondary system-md-semibold">{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>
|
||||
|
||||
@@ -112,7 +112,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 text-text-secondary system-md-semibold">
|
||||
{t('email', { ns: 'login' })}
|
||||
</label>
|
||||
<div className="mt-1">
|
||||
@@ -130,7 +130,7 @@ export default function MailAndPasswordAuth({ isEmailSetup }: MailAndPasswordAut
|
||||
|
||||
<div className="mb-3">
|
||||
<label htmlFor="password" className="my-2 flex items-center justify-between">
|
||||
<span className="system-md-semibold text-text-secondary">{t('password', { ns: 'login' })}</span>
|
||||
<span className="text-text-secondary system-md-semibold">{t('password', { ns: 'login' })}</span>
|
||||
<Link
|
||||
href={`/webapp-reset-password?${searchParams.toString()}`}
|
||||
className={`system-xs-regular ${isEmailSetup ? 'text-components-button-secondary-accent-text' : 'pointer-events-none text-components-button-secondary-accent-text-disabled'}`}
|
||||
|
||||
@@ -21,7 +21,7 @@ export default function SignInLayout({ children }: PropsWithChildren) {
|
||||
</div>
|
||||
</div>
|
||||
{systemFeatures.branding.enabled === false && (
|
||||
<div className="system-xs-regular px-8 py-6 text-text-tertiary">
|
||||
<div className="px-8 py-6 text-text-tertiary system-xs-regular">
|
||||
©
|
||||
{' '}
|
||||
{new Date().getFullYear()}
|
||||
|
||||
@@ -60,8 +60,8 @@ const NormalForm = () => {
|
||||
<RiContractLine className="h-5 w-5" />
|
||||
<RiErrorWarningFill className="absolute -right-1 -top-1 h-4 w-4 text-text-warning-secondary" />
|
||||
</div>
|
||||
<p className="system-sm-medium text-text-primary">{t('licenseLost', { ns: 'login' })}</p>
|
||||
<p className="system-xs-regular mt-1 text-text-tertiary">{t('licenseLostTip', { ns: 'login' })}</p>
|
||||
<p className="text-text-primary system-sm-medium">{t('licenseLost', { ns: 'login' })}</p>
|
||||
<p className="mt-1 text-text-tertiary system-xs-regular">{t('licenseLostTip', { ns: 'login' })}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -76,8 +76,8 @@ const NormalForm = () => {
|
||||
<RiContractLine className="h-5 w-5" />
|
||||
<RiErrorWarningFill className="absolute -right-1 -top-1 h-4 w-4 text-text-warning-secondary" />
|
||||
</div>
|
||||
<p className="system-sm-medium text-text-primary">{t('licenseExpired', { ns: 'login' })}</p>
|
||||
<p className="system-xs-regular mt-1 text-text-tertiary">{t('licenseExpiredTip', { ns: 'login' })}</p>
|
||||
<p className="text-text-primary system-sm-medium">{t('licenseExpired', { ns: 'login' })}</p>
|
||||
<p className="mt-1 text-text-tertiary system-xs-regular">{t('licenseExpiredTip', { ns: 'login' })}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -92,8 +92,8 @@ const NormalForm = () => {
|
||||
<RiContractLine className="h-5 w-5" />
|
||||
<RiErrorWarningFill className="absolute -right-1 -top-1 h-4 w-4 text-text-warning-secondary" />
|
||||
</div>
|
||||
<p className="system-sm-medium text-text-primary">{t('licenseInactive', { ns: 'login' })}</p>
|
||||
<p className="system-xs-regular mt-1 text-text-tertiary">{t('licenseInactiveTip', { ns: 'login' })}</p>
|
||||
<p className="text-text-primary system-sm-medium">{t('licenseInactive', { ns: 'login' })}</p>
|
||||
<p className="mt-1 text-text-tertiary system-xs-regular">{t('licenseInactiveTip', { ns: 'login' })}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -104,8 +104,8 @@ const NormalForm = () => {
|
||||
<>
|
||||
<div className="mx-auto mt-8 w-full">
|
||||
<div className="mx-auto w-full">
|
||||
<h2 className="title-4xl-semi-bold text-text-primary">{systemFeatures.branding.enabled ? t('pageTitleForE', { ns: 'login' }) : t('pageTitle', { ns: 'login' })}</h2>
|
||||
<p className="body-md-regular mt-2 text-text-tertiary">{t('welcome', { ns: 'login' })}</p>
|
||||
<h2 className="text-text-primary title-4xl-semi-bold">{systemFeatures.branding.enabled ? t('pageTitleForE', { ns: 'login' }) : t('pageTitle', { ns: 'login' })}</h2>
|
||||
<p className="mt-2 text-text-tertiary body-md-regular">{t('welcome', { ns: 'login' })}</p>
|
||||
</div>
|
||||
<div className="relative">
|
||||
<div className="mt-6 flex flex-col gap-3">
|
||||
@@ -122,7 +122,7 @@ const NormalForm = () => {
|
||||
<div className="h-px w-full bg-gradient-to-r from-background-gradient-mask-transparent via-divider-regular to-background-gradient-mask-transparent"></div>
|
||||
</div>
|
||||
<div className="relative flex justify-center">
|
||||
<span className="system-xs-medium-uppercase px-2 text-text-tertiary">{t('or', { ns: 'login' })}</span>
|
||||
<span className="px-2 text-text-tertiary system-xs-medium-uppercase">{t('or', { ns: 'login' })}</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -134,7 +134,7 @@ const NormalForm = () => {
|
||||
<MailAndCodeAuth />
|
||||
{systemFeatures.enable_email_password_login && (
|
||||
<div className="cursor-pointer py-1 text-center" onClick={() => { updateAuthType('password') }}>
|
||||
<span className="system-xs-medium text-components-button-secondary-accent-text">{t('usePassword', { ns: 'login' })}</span>
|
||||
<span className="text-components-button-secondary-accent-text system-xs-medium">{t('usePassword', { ns: 'login' })}</span>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
@@ -144,7 +144,7 @@ const NormalForm = () => {
|
||||
<MailAndPasswordAuth isEmailSetup={systemFeatures.is_email_setup} />
|
||||
{systemFeatures.enable_email_code_login && (
|
||||
<div className="cursor-pointer py-1 text-center" onClick={() => { updateAuthType('code') }}>
|
||||
<span className="system-xs-medium text-components-button-secondary-accent-text">{t('useVerificationCode', { ns: 'login' })}</span>
|
||||
<span className="text-components-button-secondary-accent-text system-xs-medium">{t('useVerificationCode', { ns: 'login' })}</span>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
@@ -158,8 +158,8 @@ const NormalForm = () => {
|
||||
<div className="shadows-shadow-lg mb-2 flex h-10 w-10 items-center justify-center rounded-xl bg-components-card-bg shadow">
|
||||
<RiDoorLockLine className="h-5 w-5" />
|
||||
</div>
|
||||
<p className="system-sm-medium text-text-primary">{t('noLoginMethod', { ns: 'login' })}</p>
|
||||
<p className="system-xs-regular mt-1 text-text-tertiary">{t('noLoginMethodTip', { ns: 'login' })}</p>
|
||||
<p className="text-text-primary system-sm-medium">{t('noLoginMethod', { ns: 'login' })}</p>
|
||||
<p className="mt-1 text-text-tertiary system-xs-regular">{t('noLoginMethodTip', { ns: 'login' })}</p>
|
||||
</div>
|
||||
<div className="relative my-2 py-2">
|
||||
<div className="absolute inset-0 flex items-center" aria-hidden="true">
|
||||
@@ -170,11 +170,11 @@ const NormalForm = () => {
|
||||
)}
|
||||
{!systemFeatures.branding.enabled && (
|
||||
<>
|
||||
<div className="system-xs-regular mt-2 block w-full text-text-tertiary">
|
||||
<div className="mt-2 block w-full text-text-tertiary system-xs-regular">
|
||||
{t('tosDesc', { ns: 'login' })}
|
||||
|
||||
<Link
|
||||
className="system-xs-medium text-text-secondary hover:underline"
|
||||
className="text-text-secondary system-xs-medium hover:underline"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href="https://dify.ai/terms"
|
||||
@@ -183,7 +183,7 @@ const NormalForm = () => {
|
||||
</Link>
|
||||
&
|
||||
<Link
|
||||
className="system-xs-medium text-text-secondary hover:underline"
|
||||
className="text-text-secondary system-xs-medium hover:underline"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href="https://dify.ai/privacy"
|
||||
@@ -192,11 +192,11 @@ const NormalForm = () => {
|
||||
</Link>
|
||||
</div>
|
||||
{IS_CE_EDITION && (
|
||||
<div className="w-hull system-xs-regular mt-2 block text-text-tertiary">
|
||||
<div className="w-hull mt-2 block text-text-tertiary system-xs-regular">
|
||||
{t('goToInit', { ns: 'login' })}
|
||||
|
||||
<Link
|
||||
className="system-xs-medium text-text-secondary hover:underline"
|
||||
className="text-text-secondary system-xs-medium hover:underline"
|
||||
href="/install"
|
||||
>
|
||||
{t('setAdminAccount', { ns: 'login' })}
|
||||
|
||||
@@ -45,7 +45,7 @@ const WebSSOForm: FC = () => {
|
||||
if (!systemFeatures.webapp_auth.enabled) {
|
||||
return (
|
||||
<div className="flex h-full items-center justify-center">
|
||||
<p className="system-xs-regular text-text-tertiary">{t('webapp.disabled', { ns: 'login' })}</p>
|
||||
<p className="text-text-tertiary system-xs-regular">{t('webapp.disabled', { ns: 'login' })}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -63,7 +63,7 @@ const WebSSOForm: FC = () => {
|
||||
return (
|
||||
<div className="flex h-full flex-col items-center justify-center gap-y-4">
|
||||
<AppUnavailable className="h-auto w-auto" isUnknownReason={true} />
|
||||
<span className="system-sm-regular cursor-pointer text-text-tertiary" onClick={backToHome}>{t('login.backToHome', { ns: 'share' })}</span>
|
||||
<span className="cursor-pointer text-text-tertiary system-sm-regular" onClick={backToHome}>{t('login.backToHome', { ns: 'share' })}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ const AvatarWithEdit = ({ onSave, ...props }: AvatarWithEditProps) => {
|
||||
isShow={isShowDeleteConfirm}
|
||||
onClose={() => setIsShowDeleteConfirm(false)}
|
||||
>
|
||||
<div className="title-2xl-semi-bold mb-3 text-text-primary">{t('avatar.deleteTitle', { ns: 'common' })}</div>
|
||||
<div className="mb-3 text-text-primary title-2xl-semi-bold">{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">
|
||||
|
||||
@@ -209,14 +209,14 @@ const EmailChangeModal = ({ onClose, email, show }: Props) => {
|
||||
</div>
|
||||
{step === STEP.start && (
|
||||
<>
|
||||
<div className="title-2xl-semi-bold pb-3 text-text-primary">{t('account.changeEmail.title', { ns: 'common' })}</div>
|
||||
<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="body-md-medium text-text-warning">{t('account.changeEmail.authTip', { ns: 'common' })}</div>
|
||||
<div className="body-md-regular text-text-secondary">
|
||||
<div className="text-text-warning body-md-medium">{t('account.changeEmail.authTip', { ns: 'common' })}</div>
|
||||
<div className="text-text-secondary body-md-regular">
|
||||
<Trans
|
||||
i18nKey="account.changeEmail.content1"
|
||||
ns="common"
|
||||
components={{ email: <span className="body-md-medium text-text-primary"></span> }}
|
||||
components={{ email: <span className="text-text-primary body-md-medium"></span> }}
|
||||
values={{ email }}
|
||||
/>
|
||||
</div>
|
||||
@@ -241,19 +241,19 @@ const EmailChangeModal = ({ onClose, email, show }: Props) => {
|
||||
)}
|
||||
{step === STEP.verifyOrigin && (
|
||||
<>
|
||||
<div className="title-2xl-semi-bold pb-3 text-text-primary">{t('account.changeEmail.verifyEmail', { ns: 'common' })}</div>
|
||||
<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="body-md-regular text-text-secondary">
|
||||
<div className="text-text-secondary body-md-regular">
|
||||
<Trans
|
||||
i18nKey="account.changeEmail.content2"
|
||||
ns="common"
|
||||
components={{ email: <span className="body-md-medium text-text-primary"></span> }}
|
||||
components={{ email: <span className="text-text-primary body-md-medium"></span> }}
|
||||
values={{ email }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="pt-3">
|
||||
<div className="system-sm-medium mb-1 flex h-6 items-center text-text-secondary">{t('account.changeEmail.codeLabel', { ns: 'common' })}</div>
|
||||
<div className="mb-1 flex h-6 items-center text-text-secondary system-sm-medium">{t('account.changeEmail.codeLabel', { ns: 'common' })}</div>
|
||||
<Input
|
||||
className="!w-full"
|
||||
placeholder={t('account.changeEmail.codePlaceholder', { ns: 'common' })}
|
||||
@@ -278,25 +278,25 @@ const EmailChangeModal = ({ onClose, email, show }: Props) => {
|
||||
{t('operation.cancel', { ns: 'common' })}
|
||||
</Button>
|
||||
</div>
|
||||
<div className="system-xs-regular mt-3 flex items-center gap-1 text-text-tertiary">
|
||||
<div className="mt-3 flex items-center gap-1 text-text-tertiary system-xs-regular">
|
||||
<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="system-xs-medium cursor-pointer text-text-accent-secondary">{t('account.changeEmail.resend', { ns: 'common' })}</span>
|
||||
<span onClick={sendCodeToOriginEmail} className="cursor-pointer text-text-accent-secondary system-xs-medium">{t('account.changeEmail.resend', { ns: 'common' })}</span>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{step === STEP.newEmail && (
|
||||
<>
|
||||
<div className="title-2xl-semi-bold pb-3 text-text-primary">{t('account.changeEmail.newEmail', { ns: 'common' })}</div>
|
||||
<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="body-md-regular text-text-secondary">{t('account.changeEmail.content3', { ns: 'common' })}</div>
|
||||
<div className="text-text-secondary body-md-regular">{t('account.changeEmail.content3', { ns: 'common' })}</div>
|
||||
</div>
|
||||
<div className="pt-3">
|
||||
<div className="system-sm-medium mb-1 flex h-6 items-center text-text-secondary">{t('account.changeEmail.emailLabel', { ns: 'common' })}</div>
|
||||
<div className="mb-1 flex h-6 items-center text-text-secondary system-sm-medium">{t('account.changeEmail.emailLabel', { ns: 'common' })}</div>
|
||||
<Input
|
||||
className="!w-full"
|
||||
placeholder={t('account.changeEmail.emailPlaceholder', { ns: 'common' })}
|
||||
@@ -305,10 +305,10 @@ const EmailChangeModal = ({ onClose, email, show }: Props) => {
|
||||
destructive={newEmailExited || unAvailableEmail}
|
||||
/>
|
||||
{newEmailExited && (
|
||||
<div className="body-xs-regular mt-1 py-0.5 text-text-destructive">{t('account.changeEmail.existingEmail', { ns: 'common' })}</div>
|
||||
<div className="mt-1 py-0.5 text-text-destructive body-xs-regular">{t('account.changeEmail.existingEmail', { ns: 'common' })}</div>
|
||||
)}
|
||||
{unAvailableEmail && (
|
||||
<div className="body-xs-regular mt-1 py-0.5 text-text-destructive">{t('account.changeEmail.unAvailableEmail', { ns: 'common' })}</div>
|
||||
<div className="mt-1 py-0.5 text-text-destructive body-xs-regular">{t('account.changeEmail.unAvailableEmail', { ns: 'common' })}</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-3 space-y-2">
|
||||
@@ -331,19 +331,19 @@ const EmailChangeModal = ({ onClose, email, show }: Props) => {
|
||||
)}
|
||||
{step === STEP.verifyNew && (
|
||||
<>
|
||||
<div className="title-2xl-semi-bold pb-3 text-text-primary">{t('account.changeEmail.verifyNew', { ns: 'common' })}</div>
|
||||
<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="body-md-regular text-text-secondary">
|
||||
<div className="text-text-secondary body-md-regular">
|
||||
<Trans
|
||||
i18nKey="account.changeEmail.content4"
|
||||
ns="common"
|
||||
components={{ email: <span className="body-md-medium text-text-primary"></span> }}
|
||||
components={{ email: <span className="text-text-primary body-md-medium"></span> }}
|
||||
values={{ email: mail }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="pt-3">
|
||||
<div className="system-sm-medium mb-1 flex h-6 items-center text-text-secondary">{t('account.changeEmail.codeLabel', { ns: 'common' })}</div>
|
||||
<div className="mb-1 flex h-6 items-center text-text-secondary system-sm-medium">{t('account.changeEmail.codeLabel', { ns: 'common' })}</div>
|
||||
<Input
|
||||
className="!w-full"
|
||||
placeholder={t('account.changeEmail.codePlaceholder', { ns: 'common' })}
|
||||
@@ -368,13 +368,13 @@ const EmailChangeModal = ({ onClose, email, show }: Props) => {
|
||||
{t('operation.cancel', { ns: 'common' })}
|
||||
</Button>
|
||||
</div>
|
||||
<div className="system-xs-regular mt-3 flex items-center gap-1 text-text-tertiary">
|
||||
<div className="mt-3 flex items-center gap-1 text-text-tertiary system-xs-regular">
|
||||
<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="system-xs-medium cursor-pointer text-text-accent-secondary">{t('account.changeEmail.resend', { ns: 'common' })}</span>
|
||||
<span onClick={sendCodeToNewEmail} className="cursor-pointer text-text-accent-secondary system-xs-medium">{t('account.changeEmail.resend', { ns: 'common' })}</span>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -145,7 +145,7 @@ export default function AccountPage() {
|
||||
imageUrl={icon_url}
|
||||
/>
|
||||
</div>
|
||||
<div className="system-sm-medium mt-[3px] text-text-secondary">{item.name}</div>
|
||||
<div className="mt-[3px] text-text-secondary system-sm-medium">{item.name}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -153,12 +153,12 @@ export default function AccountPage() {
|
||||
return (
|
||||
<>
|
||||
<div className="pb-3 pt-2">
|
||||
<h4 className="title-2xl-semi-bold text-text-primary">{t('account.myAccount', { ns: 'common' })}</h4>
|
||||
<h4 className="text-text-primary title-2xl-semi-bold">{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="system-xl-semibold text-text-primary">
|
||||
<p className="text-text-primary system-xl-semibold">
|
||||
{userProfile.name}
|
||||
{isEducationAccount && (
|
||||
<PremiumBadge size="s" color="blue" className="ml-1 !px-2">
|
||||
@@ -167,16 +167,16 @@ export default function AccountPage() {
|
||||
</PremiumBadge>
|
||||
)}
|
||||
</p>
|
||||
<p className="system-xs-regular text-text-tertiary">{userProfile.email}</p>
|
||||
<p className="text-text-tertiary system-xs-regular">{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="system-sm-regular flex-1 rounded-lg bg-components-input-bg-normal p-2 text-components-input-text-filled ">
|
||||
<div className="flex-1 rounded-lg bg-components-input-bg-normal p-2 text-components-input-text-filled system-sm-regular">
|
||||
<span className="pl-1">{userProfile.name}</span>
|
||||
</div>
|
||||
<div className="system-sm-medium cursor-pointer rounded-lg bg-components-button-tertiary-bg px-3 py-2 text-components-button-tertiary-text" onClick={handleEditName}>
|
||||
<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}>
|
||||
{t('operation.edit', { ns: 'common' })}
|
||||
</div>
|
||||
</div>
|
||||
@@ -184,11 +184,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="system-sm-regular flex-1 rounded-lg bg-components-input-bg-normal p-2 text-components-input-text-filled ">
|
||||
<div className="flex-1 rounded-lg bg-components-input-bg-normal p-2 text-components-input-text-filled system-sm-regular">
|
||||
<span className="pl-1">{userProfile.email}</span>
|
||||
</div>
|
||||
{systemFeatures.enable_change_email && (
|
||||
<div className="system-sm-medium cursor-pointer rounded-lg bg-components-button-tertiary-bg px-3 py-2 text-components-button-tertiary-text" onClick={() => setShowUpdateEmail(true)}>
|
||||
<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)}>
|
||||
{t('operation.change', { ns: 'common' })}
|
||||
</div>
|
||||
)}
|
||||
@@ -198,8 +198,8 @@ export default function AccountPage() {
|
||||
systemFeatures.enable_email_password_login && (
|
||||
<div className="mb-8 flex justify-between gap-2">
|
||||
<div>
|
||||
<div className="system-sm-semibold mb-1 text-text-secondary">{t('account.password', { ns: 'common' })}</div>
|
||||
<div className="body-xs-regular mb-2 text-text-tertiary">{t('account.passwordTip', { ns: 'common' })}</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>
|
||||
<Button onClick={() => setEditPasswordModalVisible(true)}>{userProfile.is_password_set ? t('account.resetPassword', { ns: 'common' }) : t('account.setPassword', { ns: 'common' })}</Button>
|
||||
</div>
|
||||
@@ -226,7 +226,7 @@ export default function AccountPage() {
|
||||
onClose={() => setEditNameModalVisible(false)}
|
||||
className="!w-[420px] !p-6"
|
||||
>
|
||||
<div className="title-2xl-semi-bold mb-6 text-text-primary">{t('account.editName', { ns: 'common' })}</div>
|
||||
<div className="mb-6 text-text-primary title-2xl-semi-bold">{t('account.editName', { ns: 'common' })}</div>
|
||||
<div className={titleClassName}>{t('account.name', { ns: 'common' })}</div>
|
||||
<Input
|
||||
className="mt-2"
|
||||
@@ -256,7 +256,7 @@ export default function AccountPage() {
|
||||
}}
|
||||
className="!w-[420px] !p-6"
|
||||
>
|
||||
<div className="title-2xl-semi-bold mb-6 text-text-primary">{userProfile.is_password_set ? t('account.resetPassword', { ns: 'common' }) : t('account.setPassword', { ns: 'common' })}</div>
|
||||
<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>
|
||||
{userProfile.is_password_set && (
|
||||
<>
|
||||
<div className={titleClassName}>{t('account.currentPassword', { ns: 'common' })}</div>
|
||||
@@ -279,7 +279,7 @@ export default function AccountPage() {
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<div className="system-sm-semibold mt-8 text-text-secondary">
|
||||
<div className="mt-8 text-text-secondary system-sm-semibold">
|
||||
{userProfile.is_password_set ? t('account.newPassword', { ns: 'common' }) : t('account.password', { ns: 'common' })}
|
||||
</div>
|
||||
<div className="relative mt-2">
|
||||
@@ -298,7 +298,7 @@ export default function AccountPage() {
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="system-sm-semibold mt-8 text-text-secondary">{t('account.confirmPassword', { ns: 'common' })}</div>
|
||||
<div className="mt-8 text-text-secondary system-sm-semibold">{t('account.confirmPassword', { ns: 'common' })}</div>
|
||||
<div className="relative mt-2">
|
||||
<Input
|
||||
type={showConfirmPassword ? 'text' : 'password'}
|
||||
|
||||
@@ -77,7 +77,7 @@ export default function AppSelector() {
|
||||
<div className="p-1">
|
||||
<div className="flex flex-nowrap items-center px-3 py-2">
|
||||
<div className="grow">
|
||||
<div className="system-md-medium break-all text-text-primary">
|
||||
<div className="break-all text-text-primary system-md-medium">
|
||||
{userProfile.name}
|
||||
{isEducationAccount && (
|
||||
<PremiumBadge size="s" color="blue" className="ml-1 !px-2">
|
||||
@@ -86,7 +86,7 @@ export default function AppSelector() {
|
||||
</PremiumBadge>
|
||||
)}
|
||||
</div>
|
||||
<div className="system-xs-regular break-all text-text-tertiary">{userProfile.email}</div>
|
||||
<div className="break-all text-text-tertiary system-xs-regular">{userProfile.email}</div>
|
||||
</div>
|
||||
<Avatar avatar={userProfile.avatar_url} name={userProfile.name} />
|
||||
</div>
|
||||
|
||||
@@ -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 text-text-destructive body-md-medium">
|
||||
{t('account.deleteTip', { ns: 'common' })}
|
||||
</div>
|
||||
<div className="body-md-regular pb-2 pt-1 text-text-secondary">
|
||||
<div className="pb-2 pt-1 text-text-secondary body-md-regular">
|
||||
{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="mb-1 mt-3 flex h-6 items-center text-text-secondary system-sm-semibold">{t('account.deleteLabel', { ns: 'common' })}</label>
|
||||
<Input
|
||||
placeholder={t('account.deletePlaceholder', { ns: 'common' }) as string}
|
||||
onChange={(e) => {
|
||||
|
||||
@@ -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="mb-1 mt-3 flex items-center text-text-secondary system-sm-semibold">{t('account.feedbackLabel', { ns: 'common' })}</label>
|
||||
<Textarea
|
||||
rows={6}
|
||||
value={userFeedback}
|
||||
|
||||
@@ -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 text-text-destructive body-md-medium">
|
||||
{t('account.deleteTip', { ns: 'common' })}
|
||||
</div>
|
||||
<div className="body-md-regular pb-2 pt-1 text-text-secondary">
|
||||
<div className="pb-2 pt-1 text-text-secondary body-md-regular">
|
||||
{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="mb-1 mt-3 flex h-6 items-center text-text-secondary system-sm-semibold">{t('account.verificationLabel', { ns: 'common' })}</label>
|
||||
<Input
|
||||
minLength={6}
|
||||
maxLength={6}
|
||||
|
||||
@@ -32,10 +32,10 @@ const Header = () => {
|
||||
: <DifyLogo />}
|
||||
</div>
|
||||
<div className="h-4 w-[1px] 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] text-text-primary title-3xl-semi-bold">{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" />
|
||||
|
||||
@@ -31,7 +31,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 text-text-primary system-xs-semibold">{name}</div>
|
||||
<Textarea
|
||||
value={content}
|
||||
onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => onChange(e.target.value)}
|
||||
|
||||
@@ -99,7 +99,7 @@ const AddAnnotationModal: FC<Props> = ({
|
||||
<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-bl-xl rounded-br-xl border-t border-divider-subtle bg-background-section-burn px-4 text-text-tertiary system-sm-medium">
|
||||
<div
|
||||
className="flex items-center space-x-2"
|
||||
>
|
||||
|
||||
@@ -33,7 +33,7 @@ const CSVDownload: FC = () => {
|
||||
|
||||
return (
|
||||
<div className="mt-6">
|
||||
<div className="system-sm-medium text-text-primary">{t('generation.csvStructureTitle', { ns: 'share' })}</div>
|
||||
<div className="text-text-primary system-sm-medium">{t('generation.csvStructureTitle', { ns: 'share' })}</div>
|
||||
<div className="mt-2 max-h-[500px] overflow-auto">
|
||||
<table className="w-full table-fixed border-separate border-spacing-0 rounded-lg border border-divider-regular text-xs">
|
||||
<thead className="text-text-tertiary">
|
||||
@@ -77,7 +77,7 @@ const CSVDownload: FC = () => {
|
||||
bom={true}
|
||||
data={getTemplate()}
|
||||
>
|
||||
<div className="system-xs-medium flex h-[18px] items-center space-x-1 text-text-accent">
|
||||
<div className="flex h-[18px] items-center space-x-1 text-text-accent system-xs-medium">
|
||||
<DownloadIcon className="mr-1 h-3 w-3" />
|
||||
{t('batchModal.template', { ns: 'appAnnotation' })}
|
||||
</div>
|
||||
|
||||
@@ -94,7 +94,7 @@ const CSVUploader: FC<Props> = ({
|
||||
/>
|
||||
<div ref={dropRef}>
|
||||
{!file && (
|
||||
<div className={cn('system-sm-regular flex h-20 items-center rounded-xl border border-dashed border-components-dropzone-border bg-components-dropzone-bg', dragging && 'border border-components-dropzone-border-accent bg-components-dropzone-bg-accent')}>
|
||||
<div className={cn('flex h-20 items-center rounded-xl border border-dashed border-components-dropzone-border bg-components-dropzone-bg system-sm-regular', dragging && 'border border-components-dropzone-border-accent bg-components-dropzone-bg-accent')}>
|
||||
<div className="flex w-full items-center justify-center space-x-2">
|
||||
<CSVIcon className="shrink-0" />
|
||||
<div className="text-text-tertiary">
|
||||
|
||||
@@ -52,7 +52,7 @@ const BatchModal: FC<IBatchModalProps> = ({
|
||||
const res = await checkAnnotationBatchImportProgress({ jobID, appId })
|
||||
setImportStatus(res.job_status)
|
||||
if (res.job_status === ProcessStatus.WAITING || res.job_status === ProcessStatus.PROCESSING)
|
||||
setTimeout(() => checkProcess(res.job_id), 2500)
|
||||
setTimeout(checkProcess, 2500, res.job_id)
|
||||
if (res.job_status === ProcessStatus.ERROR)
|
||||
notify({ type: 'error', message: `${t('batchModal.runError', { ns: 'appAnnotation' })}` })
|
||||
if (res.job_status === ProcessStatus.COMPLETED) {
|
||||
@@ -90,7 +90,7 @@ 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="relative pb-1 text-text-primary system-xl-medium">{t('batchModal.title', { ns: 'appAnnotation' })}</div>
|
||||
<div className="absolute right-4 top-4 cursor-pointer p-2" onClick={onCancel}>
|
||||
<RiCloseLine className="h-4 w-4 text-text-tertiary" />
|
||||
</div>
|
||||
@@ -107,7 +107,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 text-text-tertiary system-sm-medium" onClick={onCancel}>
|
||||
{t('batchModal.cancel', { ns: 'appAnnotation' })}
|
||||
</Button>
|
||||
<Button
|
||||
|
||||
@@ -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 text-text-tertiary system-xs-medium')}>
|
||||
<RiEditFill className="mr-1 h-3.5 w-3.5" />
|
||||
<div>{title}</div>
|
||||
<div
|
||||
@@ -75,21 +75,21 @@ const EditItem: FC<Props> = ({
|
||||
{avatar}
|
||||
</div>
|
||||
<div className="grow">
|
||||
<div className="system-xs-semibold mb-1 text-text-primary">{name}</div>
|
||||
<div className="system-sm-regular text-text-primary">{content}</div>
|
||||
<div className="mb-1 text-text-primary system-xs-semibold">{name}</div>
|
||||
<div className="text-text-primary system-sm-regular">{content}</div>
|
||||
{!isEdit
|
||||
? (
|
||||
<div>
|
||||
{showNewContent && (
|
||||
<div className="mt-3">
|
||||
<EditTitle title={editTitle} />
|
||||
<div className="system-sm-regular mt-1 text-text-primary">{newContent}</div>
|
||||
<div className="mt-1 text-text-primary system-sm-regular">{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 text-text-accent system-xs-medium"
|
||||
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 text-text-tertiary system-xs-medium">
|
||||
<div className="mr-2">·</div>
|
||||
<div
|
||||
className="flex cursor-pointer items-center space-x-1"
|
||||
|
||||
@@ -136,7 +136,7 @@ const EditAnnotationModal: FC<Props> = ({
|
||||
{
|
||||
annotationId
|
||||
? (
|
||||
<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-bl-xl rounded-br-xl border-t border-divider-subtle bg-background-section-burn px-4 text-text-tertiary system-sm-medium">
|
||||
<div
|
||||
className="flex cursor-pointer items-center space-x-2 pl-3"
|
||||
onClick={() => setShowModal(true)}
|
||||
|
||||
@@ -17,11 +17,11 @@ const EmptyElement: FC = () => {
|
||||
return (
|
||||
<div className="flex h-full items-center justify-center">
|
||||
<div className="box-border h-fit w-[560px] rounded-2xl bg-background-section-burn px-5 py-4">
|
||||
<span className="system-md-semibold text-text-secondary">
|
||||
<span className="text-text-secondary system-md-semibold">
|
||||
{t('noData.title', { ns: 'appAnnotation' })}
|
||||
<ThreeDotsIcon className="relative -left-1.5 -top-3 inline" />
|
||||
</span>
|
||||
<div className="system-sm-regular mt-2 text-text-tertiary">
|
||||
<div className="mt-2 text-text-tertiary system-sm-regular">
|
||||
{t('noData.description', { ns: 'appAnnotation' })}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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 text-text-secondary system-sm-regular">{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 text-text-secondary system-sm-regular">{t('table.header.bulkExport', { ns: 'appAnnotation' })}</span>
|
||||
<ChevronRight className="h-[14px] w-[14px] shrink-0 text-text-tertiary" />
|
||||
</MenuButton>
|
||||
<Transition
|
||||
@@ -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 text-text-secondary system-sm-regular">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 text-text-secondary system-sm-regular">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>
|
||||
|
||||
@@ -58,7 +58,7 @@ const List: FC<Props> = ({
|
||||
<>
|
||||
<div className="relative mt-2 grow overflow-x-auto">
|
||||
<table className={cn('w-full min-w-[440px] border-collapse border-0')}>
|
||||
<thead className="system-xs-medium-uppercase text-text-tertiary">
|
||||
<thead className="text-text-tertiary system-xs-medium-uppercase">
|
||||
<tr>
|
||||
<td className="w-12 whitespace-nowrap rounded-l-lg bg-background-section-burn px-2">
|
||||
<Checkbox
|
||||
@@ -75,7 +75,7 @@ const List: FC<Props> = ({
|
||||
<td className="w-[96px] whitespace-nowrap rounded-r-lg bg-background-section-burn py-1.5 pl-3">{t('table.header.actions', { ns: 'appAnnotation' })}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="system-sm-regular text-text-secondary">
|
||||
<tbody className="text-text-secondary system-sm-regular">
|
||||
{list.map(item => (
|
||||
<tr
|
||||
key={item.id}
|
||||
|
||||
@@ -11,7 +11,7 @@ const HitHistoryNoData: FC = () => {
|
||||
<div className="inline-block rounded-lg border border-divider-subtle p-3">
|
||||
<ClockFastForward className="h-5 w-5 text-text-tertiary" />
|
||||
</div>
|
||||
<div className="system-sm-regular text-text-tertiary">{t('viewModal.noHitHistory', { ns: 'appAnnotation' })}</div>
|
||||
<div className="text-text-tertiary system-sm-regular">{t('viewModal.noHitHistory', { ns: 'appAnnotation' })}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ const ViewAnnotationModal: FC<Props> = ({
|
||||
: (
|
||||
<div>
|
||||
<table className={cn('w-full min-w-[440px] border-collapse border-0')}>
|
||||
<thead className="system-xs-medium-uppercase text-text-tertiary">
|
||||
<thead className="text-text-tertiary system-xs-medium-uppercase">
|
||||
<tr>
|
||||
<td className="w-5 whitespace-nowrap rounded-l-lg bg-background-section-burn pl-2 pr-1">{t('hitHistoryTable.query', { ns: 'appAnnotation' })}</td>
|
||||
<td className="whitespace-nowrap bg-background-section-burn py-1.5 pl-3">{t('hitHistoryTable.match', { ns: 'appAnnotation' })}</td>
|
||||
@@ -147,7 +147,7 @@ const ViewAnnotationModal: FC<Props> = ({
|
||||
<td className="w-[160px] whitespace-nowrap rounded-r-lg bg-background-section-burn py-1.5 pl-3">{t('hitHistoryTable.time', { ns: 'appAnnotation' })}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="system-sm-regular text-text-secondary">
|
||||
<tbody className="text-text-secondary system-sm-regular">
|
||||
{hitHistoryList.map(item => (
|
||||
<tr
|
||||
key={item.id}
|
||||
@@ -226,7 +226,7 @@ const ViewAnnotationModal: FC<Props> = ({
|
||||
)}
|
||||
foot={id
|
||||
? (
|
||||
<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-bl-xl rounded-br-xl border-t border-divider-subtle bg-background-section-burn px-4 text-text-tertiary system-sm-medium">
|
||||
<div
|
||||
className="flex cursor-pointer items-center space-x-2 pl-3"
|
||||
onClick={() => setShowModal(true)}
|
||||
|
||||
@@ -24,7 +24,7 @@ export default function AddMemberOrGroupDialog() {
|
||||
const selectedGroupsForBreadcrumb = useAccessControlStore(s => s.selectedGroupsForBreadcrumb)
|
||||
const debouncedKeyword = useDebounce(keyword, { wait: 500 })
|
||||
|
||||
const lastAvailableGroup = selectedGroupsForBreadcrumb[selectedGroupsForBreadcrumb.length - 1]
|
||||
const lastAvailableGroup = selectedGroupsForBreadcrumb.at(-1)
|
||||
const { isLoading, isFetchingNextPage, fetchNextPage, data } = useSearchForWhiteListCandidates({ keyword: debouncedKeyword, groupId: lastAvailableGroup?.id, resultsPerPage: 10 }, open)
|
||||
const handleKeywordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setKeyword(e.target.value)
|
||||
@@ -76,7 +76,7 @@ export default function AddMemberOrGroupDialog() {
|
||||
)
|
||||
: (
|
||||
<div className="flex h-7 items-center justify-center px-2 py-0.5">
|
||||
<span className="system-xs-regular text-text-tertiary">{t('accessControlDialog.operateGroupAndMember.noResult', { ns: 'app' })}</span>
|
||||
<span className="text-text-tertiary system-xs-regular">{t('accessControlDialog.operateGroupAndMember.noResult', { ns: 'app' })}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -115,10 +115,10 @@ function SelectedGroupsBreadCrumb() {
|
||||
}, [setSelectedGroupsForBreadcrumb])
|
||||
return (
|
||||
<div className="flex h-7 items-center gap-x-0.5 px-2 py-0.5">
|
||||
<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>
|
||||
<span className={cn('text-text-tertiary system-xs-regular', 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 text-text-tertiary system-xs-regular">
|
||||
<span>/</span>
|
||||
<span className={index === selectedGroupsForBreadcrumb.length - 1 ? '' : 'cursor-pointer text-text-accent'} onClick={() => handleBreadCrumbClick(index)}>{group.name}</span>
|
||||
</div>
|
||||
@@ -161,8 +161,8 @@ 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="system-xs-regular text-text-tertiary">{group.groupSize}</p>
|
||||
<p className="mr-1 text-text-secondary system-sm-medium">{group.name}</p>
|
||||
<p className="text-text-tertiary system-xs-regular">{group.groupSize}</p>
|
||||
</div>
|
||||
<Button
|
||||
size="small"
|
||||
@@ -206,16 +206,16 @@ 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 text-text-secondary system-sm-medium">{member.name}</p>
|
||||
{currentUser.email === member.email && (
|
||||
<p className="system-xs-regular text-text-tertiary">
|
||||
<p className="text-text-tertiary system-xs-regular">
|
||||
(
|
||||
{t('you', { ns: 'common' })}
|
||||
)
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<p className="system-xs-regular text-text-quaternary">{member.email}</p>
|
||||
<p className="text-text-quaternary system-xs-regular">{member.email}</p>
|
||||
</BaseItem>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -68,18 +68,18 @@ export default function AccessControl(props: AccessControlProps) {
|
||||
<AccessControlDialog show onClose={onClose}>
|
||||
<div className="flex flex-col gap-y-3">
|
||||
<div className="pb-3 pl-6 pr-14 pt-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>
|
||||
<DialogTitle className="text-text-primary title-2xl-semi-bold">{t('accessControlDialog.title', { ns: 'app' })}</DialogTitle>
|
||||
<DialogDescription className="mt-1 text-text-tertiary system-xs-regular">{t('accessControlDialog.description', { ns: 'app' })}</DialogDescription>
|
||||
</div>
|
||||
<div className="flex flex-col gap-y-1 px-6 pb-3">
|
||||
<div className="leading-6">
|
||||
<p className="system-sm-medium text-text-tertiary">{t('accessControlDialog.accessLabel', { ns: 'app' })}</p>
|
||||
<p className="text-text-tertiary system-sm-medium">{t('accessControlDialog.accessLabel', { ns: 'app' })}</p>
|
||||
</div>
|
||||
<AccessControlItem type={AccessMode.ORGANIZATION}>
|
||||
<div className="flex items-center p-3">
|
||||
<div className="flex grow items-center gap-x-2">
|
||||
<RiBuildingLine className="h-4 w-4 text-text-primary" />
|
||||
<p className="system-sm-medium text-text-primary">{t('accessControlDialog.accessItems.organization', { ns: 'app' })}</p>
|
||||
<p className="text-text-primary system-sm-medium">{t('accessControlDialog.accessItems.organization', { ns: 'app' })}</p>
|
||||
</div>
|
||||
</div>
|
||||
</AccessControlItem>
|
||||
@@ -90,7 +90,7 @@ export default function AccessControl(props: AccessControlProps) {
|
||||
<div className="flex items-center p-3">
|
||||
<div className="flex grow items-center gap-x-2">
|
||||
<RiVerifiedBadgeLine className="h-4 w-4 text-text-primary" />
|
||||
<p className="system-sm-medium text-text-primary">{t('accessControlDialog.accessItems.external', { ns: 'app' })}</p>
|
||||
<p className="text-text-primary system-sm-medium">{t('accessControlDialog.accessItems.external', { ns: 'app' })}</p>
|
||||
</div>
|
||||
{!hideTip && <WebAppSSONotEnabledTip />}
|
||||
</div>
|
||||
@@ -98,7 +98,7 @@ export default function AccessControl(props: AccessControlProps) {
|
||||
<AccessControlItem type={AccessMode.PUBLIC}>
|
||||
<div className="flex items-center gap-x-2 p-3">
|
||||
<RiGlobalLine className="h-4 w-4 text-text-primary" />
|
||||
<p className="system-sm-medium text-text-primary">{t('accessControlDialog.accessItems.anyone', { ns: 'app' })}</p>
|
||||
<p className="text-text-primary system-sm-medium">{t('accessControlDialog.accessItems.anyone', { ns: 'app' })}</p>
|
||||
</div>
|
||||
</AccessControlItem>
|
||||
</div>
|
||||
|
||||
@@ -29,7 +29,7 @@ export default function SpecificGroupsOrMembers() {
|
||||
<div className="flex items-center p-3">
|
||||
<div className="flex grow items-center gap-x-2">
|
||||
<RiLockLine className="h-4 w-4 text-text-primary" />
|
||||
<p className="system-sm-medium text-text-primary">{t('accessControlDialog.accessItems.specific', { ns: 'app' })}</p>
|
||||
<p className="text-text-primary system-sm-medium">{t('accessControlDialog.accessItems.specific', { ns: 'app' })}</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
@@ -40,7 +40,7 @@ export default function SpecificGroupsOrMembers() {
|
||||
<div className="flex items-center gap-x-1 p-3">
|
||||
<div className="flex grow items-center gap-x-1">
|
||||
<RiLockLine className="h-4 w-4 text-text-primary" />
|
||||
<p className="system-sm-medium text-text-primary">{t('accessControlDialog.accessItems.specific', { ns: 'app' })}</p>
|
||||
<p className="text-text-primary system-sm-medium">{t('accessControlDialog.accessItems.specific', { ns: 'app' })}</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-x-1">
|
||||
<AddMemberOrGroupDialog />
|
||||
@@ -60,14 +60,14 @@ function RenderGroupsAndMembers() {
|
||||
const specificGroups = useAccessControlStore(s => s.specificGroups)
|
||||
const specificMembers = useAccessControlStore(s => s.specificMembers)
|
||||
if (specificGroups.length <= 0 && specificMembers.length <= 0)
|
||||
return <div className="px-2 pb-1.5 pt-5"><p className="system-xs-regular text-center text-text-tertiary">{t('accessControlDialog.noGroupsOrMembers', { ns: 'app' })}</p></div>
|
||||
return <div className="px-2 pb-1.5 pt-5"><p className="text-center text-text-tertiary system-xs-regular">{t('accessControlDialog.noGroupsOrMembers', { ns: 'app' })}</p></div>
|
||||
return (
|
||||
<>
|
||||
<p className="system-2xs-medium-uppercase sticky top-0 text-text-tertiary">{t('accessControlDialog.groups', { ns: 'app', count: specificGroups.length ?? 0 })}</p>
|
||||
<p className="sticky top-0 text-text-tertiary system-2xs-medium-uppercase">{t('accessControlDialog.groups', { ns: 'app', count: specificGroups.length ?? 0 })}</p>
|
||||
<div className="flex flex-row flex-wrap gap-1">
|
||||
{specificGroups.map((group, index) => <GroupItem key={index} group={group} />)}
|
||||
</div>
|
||||
<p className="system-2xs-medium-uppercase sticky top-0 text-text-tertiary">{t('accessControlDialog.members', { ns: 'app', count: specificMembers.length ?? 0 })}</p>
|
||||
<p className="sticky top-0 text-text-tertiary system-2xs-medium-uppercase">{t('accessControlDialog.members', { ns: 'app', count: specificMembers.length ?? 0 })}</p>
|
||||
<div className="flex flex-row flex-wrap gap-1">
|
||||
{specificMembers.map((member, index) => <MemberItem key={index} member={member} />)}
|
||||
</div>
|
||||
@@ -89,8 +89,8 @@ function GroupItem({ group }: GroupItemProps) {
|
||||
icon={<RiOrganizationChart className="h-[14px] w-[14px] text-components-avatar-shape-fill-stop-0" />}
|
||||
onRemove={handleRemoveGroup}
|
||||
>
|
||||
<p className="system-xs-regular text-text-primary">{group.name}</p>
|
||||
<p className="system-xs-regular text-text-tertiary">{group.groupSize}</p>
|
||||
<p className="text-text-primary system-xs-regular">{group.name}</p>
|
||||
<p className="text-text-tertiary system-xs-regular">{group.groupSize}</p>
|
||||
</BaseItem>
|
||||
)
|
||||
}
|
||||
@@ -109,7 +109,7 @@ function MemberItem({ member }: MemberItemProps) {
|
||||
icon={<Avatar size="xxs" avatar={null} name={member.name} />}
|
||||
onRemove={handleRemoveMember}
|
||||
>
|
||||
<p className="system-xs-regular text-text-primary">{member.name}</p>
|
||||
<p className="text-text-primary system-xs-regular">{member.name}</p>
|
||||
</BaseItem>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ const SuggestedAction = ({ icon, link, disabled, children, className, onClick, .
|
||||
{...props}
|
||||
>
|
||||
<div className="relative h-4 w-4">{icon}</div>
|
||||
<div className="system-sm-medium shrink grow basis-0">{children}</div>
|
||||
<div className="shrink grow basis-0 system-sm-medium">{children}</div>
|
||||
<RiArrowRightUpLine className="h-3.5 w-3.5" />
|
||||
</a>
|
||||
)
|
||||
|
||||
@@ -74,7 +74,7 @@ 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="title-2xl-semi-bold text-text-primary first-letter:capitalize">
|
||||
<div className="text-text-primary title-2xl-semi-bold 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}>
|
||||
@@ -83,7 +83,7 @@ const VersionInfoModal: FC<VersionInfoModalProps> = ({
|
||||
</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 text-text-secondary system-sm-semibold">
|
||||
{t('versionHistory.editField.title', { ns: 'workflow' })}
|
||||
</div>
|
||||
<Input
|
||||
@@ -94,7 +94,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 text-text-secondary system-sm-semibold">
|
||||
{t('versionHistory.editField.releaseNotes', { ns: 'workflow' })}
|
||||
</div>
|
||||
<Textarea
|
||||
|
||||
@@ -29,7 +29,7 @@ const FeaturePanel: FC<IFeaturePanelProps> = ({
|
||||
<div className="flex h-8 items-center justify-between">
|
||||
<div className="flex shrink-0 items-center space-x-1">
|
||||
{!!headerIcon && <div className="flex h-6 w-6 items-center justify-center">{headerIcon}</div>}
|
||||
<div className="system-sm-semibold text-text-secondary">{title}</div>
|
||||
<div className="text-text-secondary system-sm-semibold">{title}</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
{!!headerRight && <div>{headerRight}</div>}
|
||||
|
||||
@@ -2,25 +2,19 @@ import { fireEvent, render, screen } from '@testing-library/react'
|
||||
import * as React from 'react'
|
||||
import HasNotSetAPI from './has-not-set-api'
|
||||
|
||||
describe('HasNotSetAPI WarningMask', () => {
|
||||
it('should show default title when trial not finished', () => {
|
||||
render(<HasNotSetAPI isTrailFinished={false} onSetting={vi.fn()} />)
|
||||
describe('HasNotSetAPI', () => {
|
||||
it('should render the empty state copy', () => {
|
||||
render(<HasNotSetAPI onSetting={vi.fn()} />)
|
||||
|
||||
expect(screen.getByText('appDebug.notSetAPIKey.title')).toBeInTheDocument()
|
||||
expect(screen.getByText('appDebug.notSetAPIKey.description')).toBeInTheDocument()
|
||||
expect(screen.getByText('appDebug.noModelProviderConfigured')).toBeInTheDocument()
|
||||
expect(screen.getByText('appDebug.noModelProviderConfiguredTip')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should show trail finished title when flag is true', () => {
|
||||
render(<HasNotSetAPI isTrailFinished onSetting={vi.fn()} />)
|
||||
|
||||
expect(screen.getByText('appDebug.notSetAPIKey.trailFinished')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should call onSetting when primary button clicked', () => {
|
||||
it('should call onSetting when manage models button is clicked', () => {
|
||||
const onSetting = vi.fn()
|
||||
render(<HasNotSetAPI isTrailFinished={false} onSetting={onSetting} />)
|
||||
render(<HasNotSetAPI onSetting={onSetting} />)
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: 'appDebug.notSetAPIKey.settingBtn' }))
|
||||
fireEvent.click(screen.getByRole('button', { name: 'appDebug.manageModels' }))
|
||||
expect(onSetting).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -2,38 +2,38 @@
|
||||
import type { FC } from 'react'
|
||||
import * as React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Button from '@/app/components/base/button'
|
||||
import WarningMask from '.'
|
||||
|
||||
export type IHasNotSetAPIProps = {
|
||||
isTrailFinished: boolean
|
||||
onSetting: () => void
|
||||
}
|
||||
|
||||
const icon = (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M14 6.00001L14 2.00001M14 2.00001H9.99999M14 2.00001L8 8M6.66667 2H5.2C4.0799 2 3.51984 2 3.09202 2.21799C2.71569 2.40973 2.40973 2.71569 2.21799 3.09202C2 3.51984 2 4.07989 2 5.2V10.8C2 11.9201 2 12.4802 2.21799 12.908C2.40973 13.2843 2.71569 13.5903 3.09202 13.782C3.51984 14 4.07989 14 5.2 14H10.8C11.9201 14 12.4802 14 12.908 13.782C13.2843 13.5903 13.5903 13.2843 13.782 12.908C14 12.4802 14 11.9201 14 10.8V9.33333" stroke="white" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
||||
</svg>
|
||||
|
||||
)
|
||||
|
||||
const HasNotSetAPI: FC<IHasNotSetAPIProps> = ({
|
||||
isTrailFinished,
|
||||
onSetting,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<WarningMask
|
||||
title={isTrailFinished ? t('notSetAPIKey.trailFinished', { ns: 'appDebug' }) : t('notSetAPIKey.title', { ns: 'appDebug' })}
|
||||
description={t('notSetAPIKey.description', { ns: 'appDebug' })}
|
||||
footer={(
|
||||
<Button variant="primary" className="flex space-x-2" onClick={onSetting}>
|
||||
<span>{t('notSetAPIKey.settingBtn', { ns: 'appDebug' })}</span>
|
||||
{icon}
|
||||
</Button>
|
||||
)}
|
||||
/>
|
||||
<div className="flex grow flex-col items-center justify-center pb-[120px]">
|
||||
<div className="flex w-full max-w-[400px] flex-col gap-2 px-4 py-4">
|
||||
<div className="flex h-10 w-10 items-center justify-center rounded-[10px]">
|
||||
<div className="flex h-full w-full items-center justify-center overflow-hidden rounded-[10px] border-[0.5px] border-components-card-border bg-components-card-bg p-1 shadow-lg backdrop-blur-[5px]">
|
||||
<span className="i-ri-brain-2-line h-5 w-5 text-text-tertiary" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="text-text-secondary system-md-semibold">{t('noModelProviderConfigured', { ns: 'appDebug' })}</div>
|
||||
<div className="text-text-tertiary system-xs-regular">{t('noModelProviderConfiguredTip', { ns: 'appDebug' })}</div>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="flex w-fit items-center gap-1 rounded-lg border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg px-3 py-2 shadow-xs backdrop-blur-[5px]"
|
||||
onClick={onSetting}
|
||||
>
|
||||
<span className="text-components-button-secondary-accent-text system-sm-medium">{t('manageModels', { ns: 'appDebug' })}</span>
|
||||
<span className="i-ri-arrow-right-line h-4 w-4 text-components-button-secondary-accent-text" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default React.memo(HasNotSetAPI)
|
||||
|
||||
@@ -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)',
|
||||
}}
|
||||
|
||||
@@ -28,7 +28,7 @@ const MessageTypeSelector: FC<Props> = ({
|
||||
className={cn(showOption && 'bg-indigo-100', 'flex h-7 cursor-pointer items-center space-x-0.5 rounded-lg pl-1.5 pr-1 text-indigo-800')}
|
||||
>
|
||||
<div className="text-sm font-semibold uppercase">{value}</div>
|
||||
<ChevronSelectorVertical className="h-3 w-3 " />
|
||||
<ChevronSelectorVertical className="h-3 w-3" />
|
||||
</div>
|
||||
{showOption && (
|
||||
<div className="absolute top-[30px] z-10 rounded-lg border border-components-panel-border bg-components-panel-bg p-1 shadow-lg">
|
||||
|
||||
@@ -178,7 +178,7 @@ const Prompt: FC<ISimplePromptInput> = ({
|
||||
{!noTitle && (
|
||||
<div className="flex h-11 items-center justify-between pl-3 pr-2.5">
|
||||
<div className="flex items-center space-x-1">
|
||||
<div className="h2 system-sm-semibold-uppercase text-text-secondary">{mode !== AppModeEnum.COMPLETION ? t('chatSubTitle', { ns: 'appDebug' }) : t('completionSubTitle', { ns: 'appDebug' })}</div>
|
||||
<div className="h2 text-text-secondary system-sm-semibold-uppercase">{mode !== AppModeEnum.COMPLETION ? t('chatSubTitle', { ns: 'appDebug' }) : t('completionSubTitle', { ns: 'appDebug' })}</div>
|
||||
{!readonly && (
|
||||
<Tooltip
|
||||
popupContent={(
|
||||
|
||||
@@ -482,12 +482,12 @@ const ConfigModal: FC<IConfigModalProps> = ({
|
||||
|
||||
<div className="!mt-5 flex h-6 items-center space-x-2">
|
||||
<Checkbox checked={tempPayload.required} disabled={tempPayload.hide} onCheck={() => handlePayloadChange('required')(!tempPayload.required)} />
|
||||
<span className="system-sm-semibold text-text-secondary">{t('variableConfig.required', { ns: 'appDebug' })}</span>
|
||||
<span className="text-text-secondary system-sm-semibold">{t('variableConfig.required', { ns: 'appDebug' })}</span>
|
||||
</div>
|
||||
|
||||
<div className="!mt-5 flex h-6 items-center space-x-2">
|
||||
<Checkbox checked={tempPayload.hide} disabled={tempPayload.required} onCheck={() => handlePayloadChange('hide')(!tempPayload.hide)} />
|
||||
<span className="system-sm-semibold text-text-secondary">{t('variableConfig.hide', { ns: 'appDebug' })}</span>
|
||||
<span className="text-text-secondary system-sm-semibold">{t('variableConfig.hide', { ns: 'appDebug' })}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -87,10 +87,10 @@ const ConfigSelect: FC<IConfigSelectProps> = ({
|
||||
|
||||
<div
|
||||
onClick={() => { onChange([...options, '']) }}
|
||||
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"
|
||||
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"
|
||||
>
|
||||
<RiAddLine className="h-4 w-4" />
|
||||
<div className="system-sm-medium text-[13px]">{t('variableConfig.addOption', { ns: 'appDebug' })}</div>
|
||||
<div className="text-[13px] system-sm-medium">{t('variableConfig.addOption', { ns: 'appDebug' })}</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -11,7 +11,7 @@ export type IInputTypeIconProps = {
|
||||
}
|
||||
|
||||
const IconMap = (type: IInputTypeIconProps['type'], className: string) => {
|
||||
const classNames = `w-3.5 h-3.5 ${className}`
|
||||
const classNames = `h-3.5 w-3.5 ${className}`
|
||||
const icons = {
|
||||
string: (
|
||||
<InputVarTypeIcon type={InputVarType.textInput} className={classNames} />
|
||||
|
||||
@@ -33,7 +33,7 @@ const SelectTypeItem: FC<ISelectTypeItemProps> = ({
|
||||
<div
|
||||
className={cn(
|
||||
'flex h-[58px] flex-col items-center justify-center space-y-1 rounded-lg border border-components-option-card-option-border bg-components-option-card-option-bg text-text-secondary',
|
||||
selected ? 'system-xs-medium border-[1.5px] border-components-option-card-option-selected-border bg-components-option-card-option-selected-bg shadow-xs' : ' system-xs-regular cursor-pointer hover:border-components-option-card-option-border-hover hover:bg-components-option-card-option-bg-hover hover:shadow-xs',
|
||||
selected ? 'border-[1.5px] border-components-option-card-option-selected-border bg-components-option-card-option-selected-bg shadow-xs system-xs-medium' : 'cursor-pointer system-xs-regular hover:border-components-option-card-option-border-hover hover:bg-components-option-card-option-bg-hover hover:shadow-xs',
|
||||
)}
|
||||
onClick={onClick}
|
||||
>
|
||||
|
||||
@@ -46,15 +46,15 @@ const VarItem: FC<ItemProps> = ({
|
||||
)}
|
||||
<div className="flex w-0 grow items-center">
|
||||
<div className="truncate" title={`${name} · ${label}`}>
|
||||
<span className="system-sm-medium text-text-secondary">{name}</span>
|
||||
<span className="system-xs-regular px-1 text-text-quaternary">·</span>
|
||||
<span className="system-xs-medium text-text-tertiary">{label}</span>
|
||||
<span className="text-text-secondary system-sm-medium">{name}</span>
|
||||
<span className="px-1 text-text-quaternary system-xs-regular">·</span>
|
||||
<span className="text-text-tertiary system-xs-medium">{label}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="shrink-0">
|
||||
<div className={cn('flex items-center', !readonly && 'group-hover:hidden')}>
|
||||
{required && <Badge text="required" />}
|
||||
<span className="system-xs-regular pl-2 pr-1 text-text-tertiary">{type}</span>
|
||||
<span className="pl-2 pr-1 text-text-tertiary system-xs-regular">{type}</span>
|
||||
<IconTypeIcon type={type as IInputTypeIconProps['type']} className="text-text-tertiary" />
|
||||
</div>
|
||||
<div className={cn('hidden items-center justify-end rounded-lg', !readonly && 'group-hover:flex')}>
|
||||
@@ -66,7 +66,7 @@ const VarItem: FC<ItemProps> = ({
|
||||
</div>
|
||||
<div
|
||||
data-testid="var-item-delete-btn"
|
||||
className="flex h-6 w-6 cursor-pointer items-center justify-center text-text-tertiary hover:text-text-destructive"
|
||||
className="flex h-6 w-6 cursor-pointer items-center justify-center text-text-tertiary hover:text-text-destructive"
|
||||
onClick={onRemove}
|
||||
onMouseOver={() => setIsDeleting(true)}
|
||||
onMouseLeave={() => setIsDeleting(false)}
|
||||
|
||||
@@ -35,11 +35,11 @@ const ConfigVision: FC = () => {
|
||||
|
||||
const newFeatures = produce(features, (draft) => {
|
||||
if (value) {
|
||||
draft.file!.allowed_file_types = Array.from(new Set([
|
||||
draft.file!.allowed_file_types = [...new Set([
|
||||
...(draft.file?.allowed_file_types || []),
|
||||
SupportUploadFileTypes.image,
|
||||
...(isAllowVideoUpload ? [SupportUploadFileTypes.video] : []),
|
||||
]))
|
||||
])]
|
||||
}
|
||||
else {
|
||||
draft.file!.allowed_file_types = draft.file!.allowed_file_types?.filter(
|
||||
@@ -69,7 +69,7 @@ const ConfigVision: FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex grow items-center">
|
||||
<div className="system-sm-semibold mr-1 text-text-secondary">{t('vision.name', { ns: 'appDebug' })}</div>
|
||||
<div className="mr-1 text-text-secondary system-sm-semibold">{t('vision.name', { ns: 'appDebug' })}</div>
|
||||
<Tooltip
|
||||
popupContent={(
|
||||
<div className="w-[180px]">
|
||||
@@ -83,7 +83,7 @@ const ConfigVision: FC = () => {
|
||||
? (
|
||||
<>
|
||||
<div className="mr-2 flex items-center gap-0.5">
|
||||
<div className="system-xs-medium-uppercase text-text-tertiary">{t('vision.visionSettings.resolution', { ns: 'appDebug' })}</div>
|
||||
<div className="text-text-tertiary system-xs-medium-uppercase">{t('vision.visionSettings.resolution', { ns: 'appDebug' })}</div>
|
||||
<Tooltip
|
||||
popupContent={(
|
||||
<div className="w-[180px]">
|
||||
@@ -100,7 +100,7 @@ const ConfigVision: FC = () => {
|
||||
selected={file?.image?.detail === Resolution.high}
|
||||
onSelect={noop}
|
||||
className={cn(
|
||||
'cursor-not-allowed rounded-lg px-3 hover:shadow-none',
|
||||
'cursor-not-allowed rounded-lg px-3 hover:shadow-none',
|
||||
file?.image?.detail !== Resolution.high && 'hover:border-components-option-card-option-border',
|
||||
)}
|
||||
/>
|
||||
@@ -109,7 +109,7 @@ const ConfigVision: FC = () => {
|
||||
selected={file?.image?.detail === Resolution.low}
|
||||
onSelect={noop}
|
||||
className={cn(
|
||||
'cursor-not-allowed rounded-lg px-3 hover:shadow-none',
|
||||
'cursor-not-allowed rounded-lg px-3 hover:shadow-none',
|
||||
file?.image?.detail !== Resolution.low && 'hover:border-components-option-card-option-border',
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -45,7 +45,7 @@ const ParamConfigContent: FC = () => {
|
||||
<div className="text-base font-semibold leading-6 text-text-primary">{t('vision.visionSettings.title', { ns: 'appDebug' })}</div>
|
||||
<div className="space-y-6 pt-3">
|
||||
<div>
|
||||
<div className="mb-2 flex items-center space-x-1">
|
||||
<div className="mb-2 flex items-center space-x-1">
|
||||
<div className="text-[13px] font-semibold leading-[18px] text-text-secondary">{t('vision.visionSettings.resolution', { ns: 'appDebug' })}</div>
|
||||
<Tooltip
|
||||
popupContent={(
|
||||
|
||||
@@ -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 text-text-secondary system-xs-medium">{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)
|
||||
|
||||
@@ -131,16 +131,16 @@ const SettingBuiltInTool: FC<Props> = ({
|
||||
{infoSchemas.map((item, index) => (
|
||||
<div key={index} className="py-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="code-sm-semibold text-text-secondary">{item.label[language]}</div>
|
||||
<div className="system-xs-regular text-text-tertiary">
|
||||
<div className="text-text-secondary code-sm-semibold">{item.label[language]}</div>
|
||||
<div className="text-text-tertiary system-xs-regular">
|
||||
{getType(item.type)}
|
||||
</div>
|
||||
{item.required && (
|
||||
<div className="system-xs-medium text-text-warning-secondary">{t('setBuiltInTools.required', { ns: 'tools' })}</div>
|
||||
<div className="text-text-warning-secondary system-xs-medium">{t('setBuiltInTools.required', { ns: 'tools' })}</div>
|
||||
)}
|
||||
</div>
|
||||
{item.human_description && (
|
||||
<div className="system-xs-regular mt-0.5 text-text-tertiary">
|
||||
<div className="mt-0.5 text-text-tertiary system-xs-regular">
|
||||
{item.human_description?.[language]}
|
||||
</div>
|
||||
)}
|
||||
@@ -186,7 +186,7 @@ const SettingBuiltInTool: FC<Props> = ({
|
||||
</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 text-text-accent-secondary system-xs-semibold-uppercase"
|
||||
onClick={onHide}
|
||||
>
|
||||
<RiArrowLeftLine className="h-4 w-4" />
|
||||
@@ -201,7 +201,7 @@ 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 text-text-primary system-md-semibold">{currTool?.label[language]}</div>
|
||||
{!!currTool?.description[language] && (
|
||||
<Description className="mb-2 mt-3 h-auto" text={currTool.description[language]} descriptionLineRows={2}></Description>
|
||||
)}
|
||||
@@ -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 text-text-primary system-sm-semibold-uppercase">{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>
|
||||
)}
|
||||
|
||||
@@ -96,7 +96,7 @@ const Editor: FC<Props> = ({
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className={cn(editorHeight, ' min-h-[102px] overflow-y-auto px-4 text-sm text-gray-700')}>
|
||||
<div className={cn(editorHeight, 'min-h-[102px] overflow-y-auto px-4 text-sm text-gray-700')}>
|
||||
<PromptEditor
|
||||
className={editorHeight}
|
||||
value={value}
|
||||
|
||||
@@ -45,7 +45,7 @@ const SelectItem: FC<ItemProps> = ({ text, value, Icon, isChecked, description,
|
||||
onClick={() => !disabled && onClick(value)}
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center ">
|
||||
<div className="flex items-center">
|
||||
<div className="mr-3 rounded-lg bg-indigo-50 p-1">
|
||||
<Icon className="h-4 w-4 text-indigo-600" />
|
||||
</div>
|
||||
@@ -84,7 +84,7 @@ const AssistantTypePicker: FC<Props> = ({
|
||||
<>
|
||||
<div className="my-4 h-px bg-gray-100"></div>
|
||||
<div
|
||||
className={cn(isAgent ? 'group cursor-pointer hover:bg-primary-50' : 'opacity-30', 'rounded-xl bg-gray-50 p-3 pr-4 ')}
|
||||
className={cn(isAgent ? 'group cursor-pointer hover:bg-primary-50' : 'opacity-30', 'rounded-xl bg-gray-50 p-3 pr-4')}
|
||||
onClick={() => {
|
||||
if (isAgent) {
|
||||
setOpen(false)
|
||||
@@ -93,7 +93,7 @@ const AssistantTypePicker: FC<Props> = ({
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center ">
|
||||
<div className="flex items-center">
|
||||
<div className="mr-3 rounded-lg bg-gray-200 p-1 group-hover:bg-white">
|
||||
<Settings04 className="h-4 w-4 text-gray-600 group-hover:text-[#155EEF]" />
|
||||
</div>
|
||||
|
||||
@@ -336,7 +336,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 text-text-secondary system-sm-semibold-uppercase">{t('generate.instruction', { ns: 'appDebug' })}</div>
|
||||
{isBasicMode
|
||||
? (
|
||||
<InstructionEditorInBasic
|
||||
|
||||
@@ -27,11 +27,11 @@ const IdeaOutput: FC<Props> = ({
|
||||
return (
|
||||
<div className="mt-4 text-[0px]">
|
||||
<div
|
||||
className="mb-1.5 flex cursor-pointer items-center text-sm font-medium leading-5 text-text-primary"
|
||||
className="mb-1.5 flex cursor-pointer items-center text-sm font-medium leading-5 text-text-primary"
|
||||
onClick={toggleFoldIdeaOutput}
|
||||
>
|
||||
<div className="system-sm-semibold-uppercase mr-1 text-text-secondary">{t(`${i18nPrefix}.idealOutput`, { ns: 'appDebug' })}</div>
|
||||
<div className="system-xs-regular text-text-tertiary">
|
||||
<div className="mr-1 text-text-secondary system-sm-semibold-uppercase">{t(`${i18nPrefix}.idealOutput`, { ns: 'appDebug' })}</div>
|
||||
<div className="text-text-tertiary system-xs-regular">
|
||||
(
|
||||
{t(`${i18nPrefix}.optional`, { ns: 'appDebug' })}
|
||||
)
|
||||
|
||||
@@ -45,12 +45,12 @@ const InstructionEditor: FC<Props> = ({
|
||||
const isCode = generatorType === 'code'
|
||||
const placeholder = isCode
|
||||
? (
|
||||
<div className="system-sm-regular whitespace-break-spaces !leading-6 text-text-placeholder">
|
||||
<div className="whitespace-break-spaces !leading-6 text-text-placeholder system-sm-regular">
|
||||
{t(`${i18nPrefix}.codeGenInstructionPlaceHolderLine`, { ns: 'appDebug' })}
|
||||
</div>
|
||||
)
|
||||
: (
|
||||
<div className="system-sm-regular text-text-placeholder">
|
||||
<div className="text-text-placeholder system-sm-regular">
|
||||
<div className="leading-6">{t(`${i18nPrefix}.instructionPlaceHolderTitle`, { ns: 'appDebug' })}</div>
|
||||
<div className="mt-2">
|
||||
<div>{t(`${i18nPrefix}.instructionPlaceHolderLine1`, { ns: 'appDebug' })}</div>
|
||||
@@ -109,9 +109,9 @@ const InstructionEditor: FC<Props> = ({
|
||||
editable
|
||||
isSupportFileVar={false}
|
||||
/>
|
||||
<div className="system-xs-regular absolute bottom-0 left-4 flex h-8 items-center space-x-0.5 text-components-input-text-placeholder">
|
||||
<div className="absolute bottom-0 left-4 flex h-8 items-center space-x-0.5 text-components-input-text-placeholder system-xs-regular">
|
||||
<span>{t('generate.press', { ns: 'appDebug' })}</span>
|
||||
<span className="system-kbd flex h-4 w-3.5 items-center justify-center rounded-[4px] bg-components-kbd-bg-gray text-text-placeholder">/</span>
|
||||
<span className="flex h-4 w-3.5 items-center justify-center rounded-[4px] bg-components-kbd-bg-gray text-text-placeholder system-kbd">/</span>
|
||||
<span>{t('generate.to', { ns: 'appDebug' })}</span>
|
||||
<span onClick={handleInsertVariable} className="!ml-1 cursor-pointer hover:border-b hover:border-dotted hover:border-text-tertiary hover:text-text-tertiary">{t('generate.insertContext', { ns: 'appDebug' })}</span>
|
||||
</div>
|
||||
|
||||
@@ -52,14 +52,14 @@ const VersionSelector: React.FC<VersionSelectorProps> = ({ versionLen, value, on
|
||||
asChild
|
||||
>
|
||||
|
||||
<div className={cn('system-xs-medium flex items-center text-text-tertiary', isOpen && 'text-text-secondary', moreThanOneVersion && 'cursor-pointer')}>
|
||||
<div className={cn('flex items-center text-text-tertiary system-xs-medium', isOpen && 'text-text-secondary', moreThanOneVersion && 'cursor-pointer')}>
|
||||
<div>
|
||||
{t('generate.version', { ns: 'appDebug' })}
|
||||
{' '}
|
||||
{value + 1}
|
||||
{isLatest && ` · ${t('generate.latest', { ns: 'appDebug' })}`}
|
||||
</div>
|
||||
{moreThanOneVersion && <RiArrowDownSLine className="size-3 " />}
|
||||
{moreThanOneVersion && <RiArrowDownSLine className="size-3" />}
|
||||
</div>
|
||||
</PortalToFollowElemTrigger>
|
||||
<PortalToFollowElemContent className={cn(
|
||||
@@ -71,7 +71,7 @@ const VersionSelector: React.FC<VersionSelectorProps> = ({ versionLen, value, on
|
||||
'w-[208px] rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur p-1 shadow-lg',
|
||||
)}
|
||||
>
|
||||
<div className={cn('system-xs-medium-uppercase flex h-[22px] items-center px-3 pl-3 text-text-tertiary')}>
|
||||
<div className={cn('flex h-[22px] items-center px-3 pl-3 text-text-tertiary system-xs-medium-uppercase')}>
|
||||
{t('generate.versions', { ns: 'appDebug' })}
|
||||
</div>
|
||||
{
|
||||
@@ -79,7 +79,7 @@ const VersionSelector: React.FC<VersionSelectorProps> = ({ versionLen, value, on
|
||||
<div
|
||||
key={option.value}
|
||||
className={cn(
|
||||
'system-sm-medium flex h-7 cursor-pointer items-center rounded-lg px-2 text-text-secondary hover:bg-state-base-hover',
|
||||
'flex h-7 cursor-pointer items-center rounded-lg px-2 text-text-secondary system-sm-medium hover:bg-state-base-hover',
|
||||
)}
|
||||
title={option.label}
|
||||
onClick={() => {
|
||||
|
||||
@@ -3,8 +3,10 @@ import type { FormValue } from '@/app/components/header/account-setting/model-pr
|
||||
import type { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
|
||||
import type { GenRes } from '@/service/debug'
|
||||
import type { AppModeEnum, CompletionParams, Model, ModelModeType } from '@/types/app'
|
||||
import { useSessionStorageState } from 'ahooks'
|
||||
import useBoolean from 'ahooks/lib/useBoolean'
|
||||
import {
|
||||
useBoolean,
|
||||
useSessionStorageState,
|
||||
} from 'ahooks'
|
||||
import * as React from 'react'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@@ -224,7 +226,7 @@ export const GetCodeGeneratorResModal: FC<IGetCodeGeneratorResProps> = (
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-[0px]">
|
||||
<div className="system-sm-semibold-uppercase mb-1.5 text-text-secondary">{t('codegen.instruction', { ns: 'appDebug' })}</div>
|
||||
<div className="mb-1.5 text-text-secondary system-sm-semibold-uppercase">{t('codegen.instruction', { ns: 'appDebug' })}</div>
|
||||
<InstructionEditor
|
||||
editorKey={editorKey}
|
||||
value={instruction}
|
||||
@@ -248,7 +250,7 @@ export const GetCodeGeneratorResModal: FC<IGetCodeGeneratorResProps> = (
|
||||
disabled={isLoading}
|
||||
>
|
||||
<Generator className="h-4 w-4" />
|
||||
<span className="text-xs font-semibold ">{t('codegen.generate', { ns: 'appDebug' })}</span>
|
||||
<span className="text-xs font-semibold">{t('codegen.generate', { ns: 'appDebug' })}</span>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -29,10 +29,10 @@ const ConfigAudio: FC = () => {
|
||||
|
||||
const newFeatures = produce(features, (draft) => {
|
||||
if (value) {
|
||||
draft.file!.allowed_file_types = Array.from(new Set([
|
||||
draft.file!.allowed_file_types = [...new Set([
|
||||
...(draft.file?.allowed_file_types || []),
|
||||
SupportUploadFileTypes.audio,
|
||||
]))
|
||||
])]
|
||||
}
|
||||
else {
|
||||
draft.file!.allowed_file_types = draft.file!.allowed_file_types?.filter(
|
||||
@@ -56,7 +56,7 @@ const ConfigAudio: FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex grow items-center">
|
||||
<div className="system-sm-semibold mr-1 text-text-secondary">{t('feature.audioUpload.title', { ns: 'appDebug' })}</div>
|
||||
<div className="mr-1 text-text-secondary system-sm-semibold">{t('feature.audioUpload.title', { ns: 'appDebug' })}</div>
|
||||
<Tooltip
|
||||
popupContent={(
|
||||
<div className="w-[180px]">
|
||||
|
||||
@@ -29,10 +29,10 @@ const ConfigDocument: FC = () => {
|
||||
|
||||
const newFeatures = produce(features, (draft) => {
|
||||
if (value) {
|
||||
draft.file!.allowed_file_types = Array.from(new Set([
|
||||
draft.file!.allowed_file_types = [...new Set([
|
||||
...(draft.file?.allowed_file_types || []),
|
||||
SupportUploadFileTypes.document,
|
||||
]))
|
||||
])]
|
||||
}
|
||||
else {
|
||||
draft.file!.allowed_file_types = draft.file!.allowed_file_types?.filter(
|
||||
@@ -56,7 +56,7 @@ const ConfigDocument: FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex grow items-center">
|
||||
<div className="system-sm-semibold mr-1 text-text-secondary">{t('feature.documentUpload.title', { ns: 'appDebug' })}</div>
|
||||
<div className="mr-1 text-text-secondary system-sm-semibold">{t('feature.documentUpload.title', { ns: 'appDebug' })}</div>
|
||||
<Tooltip
|
||||
popupContent={(
|
||||
<div className="w-[180px]">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -68,7 +68,7 @@ const Item: FC<ItemProps> = ({
|
||||
background={iconInfo.icon_type === 'image' ? undefined : iconInfo.icon_background}
|
||||
imageUrl={iconInfo.icon_type === 'image' ? iconInfo.icon_url : undefined}
|
||||
/>
|
||||
<div className="system-sm-medium w-0 grow truncate text-text-secondary" title={config.name}>{config.name}</div>
|
||||
<div className="w-0 grow truncate text-text-secondary system-sm-medium" title={config.name}>{config.name}</div>
|
||||
</div>
|
||||
<div className="ml-2 hidden shrink-0 items-center space-x-1 group-hover:flex">
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ const ContextVar: FC<Props> = (props) => {
|
||||
const currItem = options.find(item => item.value === value)
|
||||
const notSetVar = !currItem
|
||||
return (
|
||||
<div className={cn(notSetVar ? 'rounded-bl-xl rounded-br-xl border-[#FEF0C7] bg-[#FEF0C7]' : 'border-components-panel-border-subtle', 'flex h-12 items-center justify-between border-t px-3 ')}>
|
||||
<div className={cn(notSetVar ? 'rounded-bl-xl rounded-br-xl border-[#FEF0C7] bg-[#FEF0C7]' : 'border-components-panel-border-subtle', 'flex h-12 items-center justify-between border-t px-3')}>
|
||||
<div className="flex shrink-0 items-center space-x-1">
|
||||
<div className="p-1">
|
||||
<BracketsX className="h-4 w-4 text-text-accent" />
|
||||
|
||||
@@ -57,11 +57,11 @@ const VarPicker: FC<Props> = ({
|
||||
<PortalToFollowElemTrigger className={cn(triggerClassName)} onClick={() => setOpen(v => !v)}>
|
||||
<div className={cn(
|
||||
className,
|
||||
notSetVar ? 'border-[#FEDF89] bg-[#FFFCF5] text-[#DC6803]' : ' border-components-button-secondary-border text-text-accent hover:bg-components-button-secondary-bg',
|
||||
notSetVar ? 'border-[#FEDF89] bg-[#FFFCF5] text-[#DC6803]' : 'border-components-button-secondary-border text-text-accent hover:bg-components-button-secondary-bg',
|
||||
open ? 'bg-components-button-secondary-bg' : 'bg-transparent',
|
||||
`
|
||||
flex h-8 cursor-pointer items-center justify-center space-x-1 rounded-lg border px-2 text-[13px]
|
||||
font-medium shadow-xs
|
||||
flex h-8 cursor-pointer items-center justify-center space-x-1 rounded-lg border px-2 text-[13px]
|
||||
font-medium shadow-xs
|
||||
`,
|
||||
)}
|
||||
>
|
||||
@@ -82,7 +82,7 @@ const VarPicker: FC<Props> = ({
|
||||
<PortalToFollowElemContent style={{ zIndex: 1000 }}>
|
||||
{options.length > 0
|
||||
? (
|
||||
<div className="max-h-[50vh] w-[240px] overflow-y-auto rounded-lg border border-components-panel-border bg-components-panel-bg p-1 shadow-lg">
|
||||
<div className="max-h-[50vh] w-[240px] overflow-y-auto rounded-lg border border-components-panel-border bg-components-panel-bg p-1 shadow-lg">
|
||||
{options.map(({ name, value, type }, index) => (
|
||||
<div
|
||||
key={index}
|
||||
|
||||
@@ -44,13 +44,13 @@ const WeightedScore = ({
|
||||
disabled={readonly}
|
||||
/>
|
||||
<div className="mt-3 flex justify-between">
|
||||
<div className="system-xs-semibold-uppercase flex w-[90px] shrink-0 items-center text-util-colors-blue-light-blue-light-500">
|
||||
<div className="flex w-[90px] shrink-0 items-center text-util-colors-blue-light-blue-light-500 system-xs-semibold-uppercase">
|
||||
<div className="mr-1 truncate uppercase" title={t('weightedScore.semantic', { ns: 'dataset' }) || ''}>
|
||||
{t('weightedScore.semantic', { ns: 'dataset' })}
|
||||
</div>
|
||||
{formatNumber(value.value[0])}
|
||||
</div>
|
||||
<div className="system-xs-semibold-uppercase flex w-[90px] shrink-0 items-center justify-end text-util-colors-teal-teal-500">
|
||||
<div className="flex w-[90px] shrink-0 items-center justify-end text-util-colors-teal-teal-500 system-xs-semibold-uppercase">
|
||||
{formatNumber(value.value[1])}
|
||||
<div className="ml-1 truncate uppercase" title={t('weightedScore.keyword', { ns: 'dataset' }) || ''}>
|
||||
{t('weightedScore.keyword', { ns: 'dataset' })}
|
||||
|
||||
@@ -126,7 +126,7 @@ const SelectDataSet: FC<ISelectDataSetProps> = ({
|
||||
|
||||
{hasNoData && (
|
||||
<div
|
||||
className="mt-6 flex h-[128px] items-center justify-center space-x-1 rounded-lg border text-[13px]"
|
||||
className="mt-6 flex h-[128px] items-center justify-center space-x-1 rounded-lg border text-[13px]"
|
||||
style={{
|
||||
background: 'rgba(0, 0, 0, 0.02)',
|
||||
borderColor: 'rgba(0, 0, 0, 0.02',
|
||||
@@ -195,7 +195,7 @@ const SelectDataSet: FC<ISelectDataSetProps> = ({
|
||||
)}
|
||||
{!isLoading && (
|
||||
<div className="mt-8 flex items-center justify-between">
|
||||
<div className="text-sm font-medium text-text-secondary">
|
||||
<div className="text-sm font-medium text-text-secondary">
|
||||
{selected.length > 0 && `${selected.length} ${t('feature.dataSet.selected', { ns: 'appDebug' })}`}
|
||||
</div>
|
||||
<div className="flex space-x-2">
|
||||
|
||||
@@ -210,7 +210,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
|
||||
<div className="overflow-y-auto border-b border-divider-regular p-6 pb-[68px] pt-5">
|
||||
<div className={cn(rowClass, 'items-center')}>
|
||||
<div className={labelClass}>
|
||||
<div className="system-sm-semibold text-text-secondary">{t('form.name', { ns: 'datasetSettings' })}</div>
|
||||
<div className="text-text-secondary system-sm-semibold">{t('form.name', { ns: 'datasetSettings' })}</div>
|
||||
</div>
|
||||
<Input
|
||||
value={localeCurrentDataset.name}
|
||||
@@ -221,7 +221,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
|
||||
</div>
|
||||
<div className={cn(rowClass)}>
|
||||
<div className={labelClass}>
|
||||
<div className="system-sm-semibold text-text-secondary">{t('form.desc', { ns: 'datasetSettings' })}</div>
|
||||
<div className="text-text-secondary system-sm-semibold">{t('form.desc', { ns: 'datasetSettings' })}</div>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<Textarea
|
||||
@@ -234,7 +234,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
|
||||
</div>
|
||||
<div className={rowClass}>
|
||||
<div className={labelClass}>
|
||||
<div className="system-sm-semibold text-text-secondary">{t('form.permissions', { ns: 'datasetSettings' })}</div>
|
||||
<div className="text-text-secondary system-sm-semibold">{t('form.permissions', { ns: 'datasetSettings' })}</div>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<PermissionSelector
|
||||
@@ -250,7 +250,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
|
||||
{!!(currentDataset && currentDataset.indexing_technique) && (
|
||||
<div className={cn(rowClass)}>
|
||||
<div className={labelClass}>
|
||||
<div className="system-sm-semibold text-text-secondary">{t('form.indexMethod', { ns: 'datasetSettings' })}</div>
|
||||
<div className="text-text-secondary system-sm-semibold">{t('form.indexMethod', { ns: 'datasetSettings' })}</div>
|
||||
</div>
|
||||
<div className="grow">
|
||||
<IndexMethod
|
||||
@@ -267,7 +267,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
|
||||
{indexMethod === IndexingType.QUALIFIED && (
|
||||
<div className={cn(rowClass)}>
|
||||
<div className={labelClass}>
|
||||
<div className="system-sm-semibold text-text-secondary">{t('form.embeddingModel', { ns: 'datasetSettings' })}</div>
|
||||
<div className="text-text-secondary system-sm-semibold">{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">
|
||||
|
||||
@@ -40,7 +40,7 @@ const ExternalRetrievalSection: FC<ExternalRetrievalSectionProps> = ({
|
||||
<div className={rowClass}><Divider /></div>
|
||||
<div className={rowClass}>
|
||||
<div className={labelClass}>
|
||||
<div className="system-sm-semibold text-text-secondary">{t('form.retrievalSetting.title', { ns: 'datasetSettings' })}</div>
|
||||
<div className="text-text-secondary system-sm-semibold">{t('form.retrievalSetting.title', { ns: 'datasetSettings' })}</div>
|
||||
</div>
|
||||
<RetrievalSettings
|
||||
topK={topK}
|
||||
@@ -53,26 +53,26 @@ const ExternalRetrievalSection: FC<ExternalRetrievalSectionProps> = ({
|
||||
<div className={rowClass}><Divider /></div>
|
||||
<div className={rowClass}>
|
||||
<div className={labelClass}>
|
||||
<div className="system-sm-semibold text-text-secondary">{t('form.externalKnowledgeAPI', { ns: 'datasetSettings' })}</div>
|
||||
<div className="text-text-secondary system-sm-semibold">{t('form.externalKnowledgeAPI', { ns: 'datasetSettings' })}</div>
|
||||
</div>
|
||||
<div className="w-full max-w-[480px]">
|
||||
<div className="flex h-full items-center gap-1 rounded-lg bg-components-input-bg-normal px-3 py-2">
|
||||
<ApiConnectionMod className="h-4 w-4 text-text-secondary" />
|
||||
<div className="system-sm-medium overflow-hidden text-ellipsis text-text-secondary">
|
||||
<div className="overflow-hidden text-ellipsis text-text-secondary system-sm-medium">
|
||||
{currentDataset?.external_knowledge_info.external_knowledge_api_name}
|
||||
</div>
|
||||
<div className="system-xs-regular text-text-tertiary">·</div>
|
||||
<div className="system-xs-regular text-text-tertiary">{currentDataset?.external_knowledge_info.external_knowledge_api_endpoint}</div>
|
||||
<div className="text-text-tertiary system-xs-regular">·</div>
|
||||
<div className="text-text-tertiary system-xs-regular">{currentDataset?.external_knowledge_info.external_knowledge_api_endpoint}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={rowClass}>
|
||||
<div className={labelClass}>
|
||||
<div className="system-sm-semibold text-text-secondary">{t('form.externalKnowledgeID', { ns: 'datasetSettings' })}</div>
|
||||
<div className="text-text-secondary system-sm-semibold">{t('form.externalKnowledgeID', { ns: 'datasetSettings' })}</div>
|
||||
</div>
|
||||
<div className="w-full max-w-[480px]">
|
||||
<div className="flex h-full items-center gap-1 rounded-lg bg-components-input-bg-normal px-3 py-2">
|
||||
<div className="system-xs-regular text-text-tertiary">{currentDataset?.external_knowledge_info.external_knowledge_id}</div>
|
||||
<div className="text-text-tertiary system-xs-regular">{currentDataset?.external_knowledge_info.external_knowledge_id}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -101,7 +101,7 @@ const InternalRetrievalSection: FC<InternalRetrievalSectionProps> = ({
|
||||
<div className={rowClass}>
|
||||
<div className={cn(labelClass, 'w-auto min-w-[168px]')}>
|
||||
<div>
|
||||
<div className="system-sm-semibold text-text-secondary">{t('form.retrievalSetting.title', { ns: 'datasetSettings' })}</div>
|
||||
<div className="text-text-secondary system-sm-semibold">{t('form.retrievalSetting.title', { ns: 'datasetSettings' })}</div>
|
||||
<div className="text-xs font-normal leading-[18px] text-text-tertiary">
|
||||
<a target="_blank" rel="noopener noreferrer" href={docLink('/use-dify/knowledge/create-knowledge/setting-indexing-methods')} className="text-text-accent">{t('form.retrievalSetting.learnMore', { ns: 'datasetSettings' })}</a>
|
||||
{t('form.retrievalSetting.description', { ns: 'datasetSettings' })}
|
||||
|
||||
@@ -75,9 +75,9 @@ const ChatUserInput = ({
|
||||
>
|
||||
<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 text-text-secondary system-sm-semibold">
|
||||
<div className="truncate">{name || key}</div>
|
||||
{!required && <span className="system-xs-regular text-text-tertiary">{t('panel.optional', { ns: 'workflow' })}</span>}
|
||||
{!required && <span className="text-text-tertiary system-xs-regular">{t('panel.optional', { ns: 'workflow' })}</span>}
|
||||
</div>
|
||||
)}
|
||||
<div className="grow">
|
||||
|
||||
@@ -1,13 +1,25 @@
|
||||
import type { ReactNode } from 'react'
|
||||
import type { ModelAndParameter } from '../types'
|
||||
import type { FormValue } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import type {
|
||||
FormValue,
|
||||
ModelProvider,
|
||||
} from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import { ModelStatusEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { createMockProviderContextValue } from '@/__mocks__/provider-context'
|
||||
import {
|
||||
ConfigurationMethodEnum,
|
||||
CurrentSystemQuotaTypeEnum,
|
||||
CustomConfigurationStatusEnum,
|
||||
ModelStatusEnum,
|
||||
ModelTypeEnum,
|
||||
PreferredProviderTypeEnum,
|
||||
} from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import ModelParameterTrigger from './model-parameter-trigger'
|
||||
|
||||
const mockUseDebugConfigurationContext = vi.fn()
|
||||
const mockUseDebugWithMultipleModelContext = vi.fn()
|
||||
const mockUseLanguage = vi.fn()
|
||||
const mockUseProviderContext = vi.fn()
|
||||
const mockUseCredentialPanelState = vi.fn()
|
||||
|
||||
type RenderTriggerProps = {
|
||||
open: boolean
|
||||
@@ -35,8 +47,12 @@ vi.mock('./context', () => ({
|
||||
useDebugWithMultipleModelContext: () => mockUseDebugWithMultipleModelContext(),
|
||||
}))
|
||||
|
||||
vi.mock('@/app/components/header/account-setting/model-provider-page/hooks', () => ({
|
||||
useLanguage: () => mockUseLanguage(),
|
||||
vi.mock('@/context/provider-context', () => ({
|
||||
useProviderContext: () => mockUseProviderContext(),
|
||||
}))
|
||||
|
||||
vi.mock('@/app/components/header/account-setting/model-provider-page/provider-added-card/use-credential-panel-state', () => ({
|
||||
useCredentialPanelState: () => mockUseCredentialPanelState(),
|
||||
}))
|
||||
|
||||
vi.mock('@/app/components/header/account-setting/model-provider-page/model-parameter-modal', () => ({
|
||||
@@ -84,6 +100,41 @@ const createModelAndParameter = (overrides: Partial<ModelAndParameter> = {}): Mo
|
||||
...overrides,
|
||||
})
|
||||
|
||||
const createModelProvider = (overrides: Partial<ModelProvider> = {}): ModelProvider => ({
|
||||
provider: 'openai',
|
||||
label: { en_US: 'OpenAI', zh_Hans: 'OpenAI' },
|
||||
help: {
|
||||
title: { en_US: 'Help', zh_Hans: 'Help' },
|
||||
url: { en_US: 'https://example.com', zh_Hans: 'https://example.com' },
|
||||
},
|
||||
icon_small: { en_US: '', zh_Hans: '' },
|
||||
supported_model_types: [ModelTypeEnum.textGeneration],
|
||||
configurate_methods: [ConfigurationMethodEnum.predefinedModel],
|
||||
provider_credential_schema: {
|
||||
credential_form_schemas: [],
|
||||
},
|
||||
model_credential_schema: {
|
||||
model: {
|
||||
label: { en_US: 'Model', zh_Hans: 'Model' },
|
||||
placeholder: { en_US: 'Select model', zh_Hans: 'Select model' },
|
||||
},
|
||||
credential_form_schemas: [],
|
||||
},
|
||||
preferred_provider_type: PreferredProviderTypeEnum.custom,
|
||||
custom_configuration: {
|
||||
status: CustomConfigurationStatusEnum.active,
|
||||
current_credential_id: 'cred-1',
|
||||
current_credential_name: 'Primary Key',
|
||||
available_credentials: [{ credential_id: 'cred-1', credential_name: 'Primary Key' }],
|
||||
},
|
||||
system_configuration: {
|
||||
enabled: true,
|
||||
current_quota_type: CurrentSystemQuotaTypeEnum.trial,
|
||||
quota_configurations: [],
|
||||
},
|
||||
...overrides,
|
||||
})
|
||||
|
||||
const renderComponent = (props: Partial<{ modelAndParameter: ModelAndParameter }> = {}) => {
|
||||
const defaultProps = {
|
||||
modelAndParameter: createModelAndParameter(),
|
||||
@@ -106,8 +157,19 @@ describe('ModelParameterTrigger', () => {
|
||||
onMultipleModelConfigsChange: vi.fn(),
|
||||
onDebugWithMultipleModelChange: vi.fn(),
|
||||
})
|
||||
|
||||
mockUseLanguage.mockReturnValue('en_US')
|
||||
mockUseProviderContext.mockReturnValue(createMockProviderContextValue({
|
||||
modelProviders: [createModelProvider()],
|
||||
}))
|
||||
mockUseCredentialPanelState.mockReturnValue({
|
||||
variant: 'api-active',
|
||||
priority: 'apiKey',
|
||||
supportsCredits: true,
|
||||
showPrioritySwitcher: true,
|
||||
hasCredentials: true,
|
||||
isCreditsExhausted: false,
|
||||
credentialName: 'Primary Key',
|
||||
credits: 10,
|
||||
})
|
||||
})
|
||||
|
||||
describe('rendering', () => {
|
||||
@@ -311,23 +373,51 @@ describe('ModelParameterTrigger', () => {
|
||||
expect(screen.getByTestId('model-parameter-modal')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should render "Select Model" text when no provider/model', () => {
|
||||
renderComponent()
|
||||
it('should render "Select Model" text when no provider or model is configured', () => {
|
||||
renderComponent({
|
||||
modelAndParameter: createModelAndParameter({
|
||||
provider: '',
|
||||
model: '',
|
||||
}),
|
||||
})
|
||||
|
||||
// When currentProvider and currentModel are null, shows "Select Model"
|
||||
expect(screen.getByText('common.modelProvider.selectModel')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
describe('language context', () => {
|
||||
it('should use language from useLanguage hook', () => {
|
||||
mockUseLanguage.mockReturnValue('zh_Hans')
|
||||
|
||||
it('should render configured model id and incompatible tooltip when model is missing from the provider list', () => {
|
||||
renderComponent()
|
||||
|
||||
// The language is used for MODEL_STATUS_TEXT tooltip
|
||||
// We verify the hook is called
|
||||
expect(mockUseLanguage).toHaveBeenCalled()
|
||||
expect(screen.getByText('gpt-3.5-turbo')).toBeInTheDocument()
|
||||
expect(screen.getByTestId('tooltip')).toHaveAttribute('data-content', 'common.modelProvider.selector.incompatibleTip')
|
||||
})
|
||||
|
||||
it('should render configure required tooltip for no-configure status', () => {
|
||||
const { unmount } = renderComponent()
|
||||
const triggerContent = capturedModalProps?.renderTrigger({
|
||||
open: false,
|
||||
currentProvider: { provider: 'openai' },
|
||||
currentModel: { model: 'gpt-3.5-turbo', status: ModelStatusEnum.noConfigure },
|
||||
})
|
||||
|
||||
unmount()
|
||||
render(<>{triggerContent}</>)
|
||||
|
||||
expect(screen.getByTestId('tooltip')).toHaveAttribute('data-content', 'common.modelProvider.selector.configureRequired')
|
||||
})
|
||||
|
||||
it('should render disabled tooltip for disabled status', () => {
|
||||
const { unmount } = renderComponent()
|
||||
const triggerContent = capturedModalProps?.renderTrigger({
|
||||
open: false,
|
||||
currentProvider: { provider: 'openai' },
|
||||
currentModel: { model: 'gpt-3.5-turbo', status: ModelStatusEnum.disabled },
|
||||
})
|
||||
|
||||
unmount()
|
||||
render(<>{triggerContent}</>)
|
||||
|
||||
expect(screen.getByTestId('tooltip')).toHaveAttribute('data-content', 'common.modelProvider.selector.disabled')
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -1,22 +1,20 @@
|
||||
import type { FC } from 'react'
|
||||
import type { ModelAndParameter } from '../types'
|
||||
import type { FormValue } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { RiArrowDownSLine } from '@remixicon/react'
|
||||
import { memo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
|
||||
import { CubeOutline } from '@/app/components/base/icons/src/vender/line/shapes'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
import {
|
||||
|
||||
MODEL_STATUS_TEXT,
|
||||
ModelStatusEnum,
|
||||
} from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
DERIVED_MODEL_STATUS_BADGE_I18N,
|
||||
DERIVED_MODEL_STATUS_TOOLTIP_I18N,
|
||||
deriveModelStatus,
|
||||
} from '@/app/components/header/account-setting/model-provider-page/derive-model-status'
|
||||
import ModelIcon from '@/app/components/header/account-setting/model-provider-page/model-icon'
|
||||
import ModelName from '@/app/components/header/account-setting/model-provider-page/model-name'
|
||||
import ModelParameterModal from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal'
|
||||
import { useCredentialPanelState } from '@/app/components/header/account-setting/model-provider-page/provider-added-card/use-credential-panel-state'
|
||||
import { useDebugConfigurationContext } from '@/context/debug-configuration'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import { useDebugWithMultipleModelContext } from './context'
|
||||
|
||||
type ModelParameterTriggerProps = {
|
||||
@@ -34,8 +32,10 @@ const ModelParameterTrigger: FC<ModelParameterTriggerProps> = ({
|
||||
onMultipleModelConfigsChange,
|
||||
onDebugWithMultipleModelChange,
|
||||
} = useDebugWithMultipleModelContext()
|
||||
const language = useLanguage()
|
||||
const { modelProviders } = useProviderContext()
|
||||
const index = multipleModelConfigs.findIndex(v => v.id === modelAndParameter.id)
|
||||
const providerMeta = modelProviders.find(provider => provider.provider === modelAndParameter.provider)
|
||||
const credentialState = useCredentialPanelState(providerMeta)
|
||||
|
||||
const handleSelectModel = ({ modelId, provider }: { modelId: string, provider: string }) => {
|
||||
const newModelConfigs = [...multipleModelConfigs]
|
||||
@@ -69,55 +69,77 @@ const ModelParameterTrigger: FC<ModelParameterTriggerProps> = ({
|
||||
open,
|
||||
currentProvider,
|
||||
currentModel,
|
||||
}) => (
|
||||
<div
|
||||
className={`
|
||||
flex h-8 max-w-[200px] cursor-pointer items-center rounded-lg px-2
|
||||
${open && 'bg-state-base-hover'}
|
||||
${currentModel && currentModel.status !== ModelStatusEnum.active && '!bg-[#FFFAEB]'}
|
||||
`}
|
||||
>
|
||||
{
|
||||
currentProvider && (
|
||||
<ModelIcon
|
||||
className="mr-1 !h-4 !w-4"
|
||||
provider={currentProvider}
|
||||
modelName={currentModel?.model}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
!currentProvider && (
|
||||
<div className="mr-1 flex h-4 w-4 items-center justify-center rounded">
|
||||
<CubeOutline className="h-4 w-4 text-text-accent" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
currentModel && (
|
||||
<ModelName
|
||||
className="mr-0.5 text-text-secondary"
|
||||
modelItem={currentModel}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
!currentModel && (
|
||||
<div className="mr-0.5 truncate text-[13px] font-medium text-text-accent">
|
||||
{t('modelProvider.selectModel', { ns: 'common' })}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
<RiArrowDownSLine className={`h-3 w-3 ${(currentModel && currentProvider) ? 'text-text-tertiary' : 'text-text-accent'}`} />
|
||||
{
|
||||
currentModel && currentModel.status !== ModelStatusEnum.active && (
|
||||
<Tooltip popupContent={MODEL_STATUS_TEXT[currentModel.status][language]}>
|
||||
<AlertTriangle className="h-4 w-4 text-[#F79009]" />
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
}) => {
|
||||
const status = deriveModelStatus(
|
||||
modelAndParameter.model,
|
||||
modelAndParameter.provider,
|
||||
providerMeta,
|
||||
currentModel ?? undefined,
|
||||
credentialState,
|
||||
)
|
||||
const iconProvider = currentProvider || providerMeta
|
||||
const statusLabelKey = DERIVED_MODEL_STATUS_BADGE_I18N[status]
|
||||
const statusTooltipKey = DERIVED_MODEL_STATUS_TOOLTIP_I18N[status]
|
||||
const isEmpty = status === 'empty'
|
||||
const isActive = status === 'active'
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`
|
||||
flex h-8 max-w-[200px] cursor-pointer items-center rounded-lg px-2
|
||||
${open && 'bg-state-base-hover'}
|
||||
${!isEmpty && !isActive && '!bg-[#FFFAEB]'}
|
||||
`}
|
||||
>
|
||||
{
|
||||
iconProvider && !isEmpty && (
|
||||
<ModelIcon
|
||||
className="mr-1 !h-4 !w-4"
|
||||
provider={iconProvider}
|
||||
modelName={currentModel?.model || modelAndParameter.model}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
(!iconProvider || isEmpty) && (
|
||||
<div className="mr-1 flex h-4 w-4 items-center justify-center rounded">
|
||||
<span className="i-custom-vender-line-shapes-cube-outline h-4 w-4 text-text-accent" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
currentModel && (
|
||||
<ModelName
|
||||
className="mr-0.5 text-text-secondary"
|
||||
modelItem={currentModel}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
!currentModel && !isEmpty && (
|
||||
<div className="mr-0.5 truncate text-[13px] font-medium text-text-secondary">
|
||||
{modelAndParameter.model}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
isEmpty && (
|
||||
<div className="mr-0.5 truncate text-[13px] font-medium text-text-accent">
|
||||
{t('modelProvider.selectModel', { ns: 'common' })}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
<span className={`i-ri-arrow-down-s-line h-3 w-3 ${isEmpty ? 'text-text-accent' : 'text-text-tertiary'}`} />
|
||||
{
|
||||
!isEmpty && !isActive && statusLabelKey && (
|
||||
<Tooltip popupContent={t((statusTooltipKey || statusLabelKey) as 'modelProvider.selector.incompatible', { ns: 'common' })}>
|
||||
<span className="i-custom-vender-line-alertsAndFeedback-alert-triangle h-4 w-4 text-[#F79009]" />
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
1021
web/app/components/app/configuration/debug/index.spec.tsx
Normal file
1021
web/app/components/app/configuration/debug/index.spec.tsx
Normal file
File diff suppressed because it is too large
Load Diff
@@ -33,7 +33,7 @@ import { ToastContext } from '@/app/components/base/toast/context'
|
||||
import TooltipPlus from '@/app/components/base/tooltip'
|
||||
import { ModelFeatureEnum, ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { useDefaultModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
import { DEFAULT_CHAT_PROMPT_CONFIG, DEFAULT_COMPLETION_PROMPT_CONFIG, IS_CE_EDITION } from '@/config'
|
||||
import { DEFAULT_CHAT_PROMPT_CONFIG, DEFAULT_COMPLETION_PROMPT_CONFIG } from '@/config'
|
||||
import ConfigContext from '@/context/debug-configuration'
|
||||
import { useEventEmitterContextContext } from '@/context/event-emitter'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
@@ -394,7 +394,7 @@ const Debug: FC<IDebug> = ({
|
||||
<>
|
||||
<div className="shrink-0">
|
||||
<div className="flex items-center justify-between px-4 pb-2 pt-3">
|
||||
<div className="system-xl-semibold text-text-primary">{t('inputs.title', { ns: 'appDebug' })}</div>
|
||||
<div className="text-text-primary system-xl-semibold">{t('inputs.title', { ns: 'appDebug' })}</div>
|
||||
<div className="flex items-center">
|
||||
{
|
||||
debugWithMultipleModel
|
||||
@@ -505,6 +505,26 @@ const Debug: FC<IDebug> = ({
|
||||
{
|
||||
!debugWithMultipleModel && (
|
||||
<div className="flex grow flex-col" ref={ref}>
|
||||
{/* No model provider configured */}
|
||||
{(!modelConfig.provider || !isAPIKeySet) && (
|
||||
<HasNotSetAPIKEY onSetting={onSetting} />
|
||||
)}
|
||||
{/* No model selected */}
|
||||
{modelConfig.provider && isAPIKeySet && !modelConfig.model_id && (
|
||||
<div className="flex grow flex-col items-center justify-center pb-[120px]">
|
||||
<div className="flex w-full max-w-[400px] flex-col gap-2 px-4 py-4">
|
||||
<div className="flex h-10 w-10 items-center justify-center rounded-[10px]">
|
||||
<div className="flex h-full w-full items-center justify-center overflow-hidden rounded-[10px] border-[0.5px] border-components-card-border bg-components-card-bg p-1 shadow-lg backdrop-blur-[5px]">
|
||||
<span className="i-ri-brain-2-line h-5 w-5 text-text-tertiary" />
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{/* Chat */}
|
||||
{mode !== AppModeEnum.COMPLETION && (
|
||||
<div className="h-0 grow overflow-hidden">
|
||||
@@ -539,7 +559,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="system-sm-regular text-text-quaternary">{t('noResult', { ns: 'appDebug' })}</div>
|
||||
<div className="text-text-quaternary system-sm-regular">{t('noResult', { ns: 'appDebug' })}</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
@@ -570,7 +590,6 @@ const Debug: FC<IDebug> = ({
|
||||
/>
|
||||
)
|
||||
}
|
||||
{!isAPIKeySet && !readonly && (<HasNotSetAPIKEY isTrailFinished={!IS_CE_EDITION} onSetting={onSetting} />)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -966,10 +966,10 @@ const Configuration: FC = () => {
|
||||
<div className="bg-default-subtle absolute left-0 top-0 h-14 w-full">
|
||||
<div className="flex h-14 items-center justify-between px-6">
|
||||
<div className="flex items-center">
|
||||
<div className="system-xl-semibold text-text-primary">{t('orchestrate', { ns: 'appDebug' })}</div>
|
||||
<div className="text-text-primary system-xl-semibold">{t('orchestrate', { ns: 'appDebug' })}</div>
|
||||
<div className="flex h-[14px] items-center space-x-1 text-xs">
|
||||
{isAdvancedMode && (
|
||||
<div className="system-xs-medium-uppercase ml-1 flex h-5 items-center rounded-md border border-components-button-secondary-border px-1.5 uppercase text-text-tertiary">{t('promptMode.advanced', { ns: 'appDebug' })}</div>
|
||||
<div className="ml-1 flex h-5 items-center rounded-md border border-components-button-secondary-border px-1.5 uppercase text-text-tertiary system-xs-medium-uppercase">{t('promptMode.advanced', { ns: 'appDebug' })}</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1030,8 +1030,8 @@ const Configuration: FC = () => {
|
||||
<Config />
|
||||
</div>
|
||||
{!isMobile && (
|
||||
<div className="relative flex h-full w-1/2 grow flex-col overflow-y-auto " style={{ borderColor: 'rgba(0, 0, 0, 0.02)' }}>
|
||||
<div className="flex grow flex-col rounded-tl-2xl border-l-[0.5px] border-t-[0.5px] border-components-panel-border bg-chatbot-bg ">
|
||||
<div className="relative flex h-full w-1/2 grow flex-col overflow-y-auto" style={{ borderColor: 'rgba(0, 0, 0, 0.02)' }}>
|
||||
<div className="flex grow flex-col rounded-tl-2xl border-l-[0.5px] border-t-[0.5px] border-components-panel-border bg-chatbot-bg">
|
||||
<Debug
|
||||
isAPIKeySet={isAPIKeySet}
|
||||
onSetting={() => setShowAccountSettingModal({ payload: ACCOUNT_SETTING_TAB.PROVIDER })}
|
||||
|
||||
@@ -112,12 +112,12 @@ const PromptValuePanel: FC<IPromptValuePanelProps> = ({
|
||||
<div className="relative z-[1] mx-3 rounded-xl border-[0.5px] border-components-panel-border-subtle bg-components-panel-on-panel-item-bg shadow-md">
|
||||
<div className={cn('px-4 pt-3', userInputFieldCollapse ? 'pb-3' : 'pb-1')}>
|
||||
<div className="flex cursor-pointer items-center gap-0.5 py-0.5" onClick={() => setUserInputFieldCollapse(!userInputFieldCollapse)}>
|
||||
<div className="system-md-semibold-uppercase text-text-secondary">{t('inputs.userInputField', { ns: 'appDebug' })}</div>
|
||||
<div className="text-text-secondary system-md-semibold-uppercase">{t('inputs.userInputField', { ns: 'appDebug' })}</div>
|
||||
{userInputFieldCollapse && <RiArrowRightSLine className="h-4 w-4 text-text-secondary" />}
|
||||
{!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 text-text-tertiary system-xs-regular">{t('inputs.completionVarTip', { ns: 'appDebug' })}</div>
|
||||
)}
|
||||
</div>
|
||||
{!userInputFieldCollapse && promptVariables.length > 0 && (
|
||||
@@ -129,9 +129,9 @@ 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 text-text-secondary system-sm-semibold">
|
||||
<div className="truncate">{name || key}</div>
|
||||
{!required && <span className="system-xs-regular text-text-tertiary">{t('panel.optional', { ns: 'workflow' })}</span>}
|
||||
{!required && <span className="text-text-tertiary system-xs-regular">{t('panel.optional', { ns: 'workflow' })}</span>}
|
||||
</div>
|
||||
)}
|
||||
<div className="grow">
|
||||
|
||||
@@ -217,7 +217,7 @@ const ExternalDataToolModal: FC<ExternalDataToolModalProps> = ({
|
||||
<AppIcon
|
||||
size="large"
|
||||
onClick={() => { setShowEmojiPicker(true) }}
|
||||
className="!h-9 !w-9 cursor-pointer rounded-lg border-[0.5px] border-components-panel-border "
|
||||
className="!h-9 !w-9 cursor-pointer rounded-lg border-[0.5px] border-components-panel-border"
|
||||
icon={localeData.icon}
|
||||
background={localeData.icon_background}
|
||||
/>
|
||||
|
||||
@@ -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
|
||||
@@ -52,12 +52,12 @@ const AppCard = ({
|
||||
</div>
|
||||
<div className="flex grow flex-col gap-1">
|
||||
<div className="line-clamp-1">
|
||||
<span className="system-md-semibold text-text-secondary" title={appBasicInfo.name}>{appBasicInfo.name}</span>
|
||||
<span className="text-text-secondary system-md-semibold" title={appBasicInfo.name}>{appBasicInfo.name}</span>
|
||||
</div>
|
||||
<AppTypeLabel className="system-2xs-medium-uppercase text-text-tertiary" type={app.app.mode} />
|
||||
<AppTypeLabel className="text-text-tertiary system-2xs-medium-uppercase" type={app.app.mode} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="system-xs-regular py-1 text-text-tertiary">
|
||||
<div className="py-1 text-text-tertiary system-xs-regular">
|
||||
<div className="line-clamp-3">
|
||||
{app.description}
|
||||
</div>
|
||||
|
||||
@@ -165,7 +165,7 @@ const Apps = ({
|
||||
<div className="flex h-full flex-col">
|
||||
<div className="flex items-center justify-between border-b border-divider-burn py-3">
|
||||
<div className="min-w-[180px] pl-5">
|
||||
<span className="title-xl-semi-bold text-text-primary">{t('newApp.startFromTemplate', { ns: 'app' })}</span>
|
||||
<span className="text-text-primary title-xl-semi-bold">{t('newApp.startFromTemplate', { ns: 'app' })}</span>
|
||||
</div>
|
||||
<div className="flex max-w-[548px] flex-1 items-center rounded-xl border border-components-panel-border bg-components-panel-bg-blur p-1.5 shadow-md">
|
||||
<AppTypeSelector value={currentType} onChange={setCurrentType} />
|
||||
@@ -195,10 +195,10 @@ const Apps = ({
|
||||
<>
|
||||
<div className="pb-1 pt-4">
|
||||
{searchKeywords
|
||||
? <p className="title-md-semi-bold text-text-tertiary">{searchFilteredList.length > 1 ? t('newApp.foundResults', { ns: 'app', count: searchFilteredList.length }) : t('newApp.foundResult', { ns: 'app', count: searchFilteredList.length })}</p>
|
||||
? <p className="text-text-tertiary title-md-semi-bold">{searchFilteredList.length > 1 ? t('newApp.foundResults', { ns: 'app', count: searchFilteredList.length }) : t('newApp.foundResult', { ns: 'app', count: searchFilteredList.length })}</p>
|
||||
: (
|
||||
<div className="flex h-[22px] items-center">
|
||||
<AppCategoryLabel category={currCategory as AppCategories} className="title-md-semi-bold text-text-primary" />
|
||||
<AppCategoryLabel category={currCategory as AppCategories} className="text-text-primary title-md-semi-bold" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -250,8 +250,8 @@ function NoTemplateFound() {
|
||||
<div className="mb-2 inline-flex h-8 w-8 items-center justify-center rounded-lg bg-components-card-bg shadow-lg">
|
||||
<RiRobot2Line className="h-5 w-5 text-text-tertiary" />
|
||||
</div>
|
||||
<p className="title-md-semi-bold text-text-primary">{t('newApp.noTemplateFound', { ns: 'app' })}</p>
|
||||
<p className="system-sm-regular text-text-tertiary">{t('newApp.noTemplateFoundTip', { ns: 'app' })}</p>
|
||||
<p className="text-text-primary title-md-semi-bold">{t('newApp.noTemplateFound', { ns: 'app' })}</p>
|
||||
<p className="text-text-tertiary system-sm-regular">{t('newApp.noTemplateFoundTip', { ns: 'app' })}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ export default function Sidebar({ current, categories, onClick, onCreateFromBlan
|
||||
<ul className="pt-0.5">
|
||||
<CategoryItem category={AppCategories.RECOMMENDED} active={current === AppCategories.RECOMMENDED} onClick={onClick} />
|
||||
</ul>
|
||||
<div className="system-xs-medium-uppercase mb-0.5 mt-3 px-3 pb-1 pt-2 text-text-tertiary">{t('newAppFromTemplate.byCategories', { ns: 'app' })}</div>
|
||||
<div className="mb-0.5 mt-3 px-3 pb-1 pt-2 text-text-tertiary system-xs-medium-uppercase">{t('newAppFromTemplate.byCategories', { ns: 'app' })}</div>
|
||||
<ul className="flex grow flex-col gap-0.5">
|
||||
{categories.map(category => (<CategoryItem key={category} category={category} active={current === category} onClick={onClick} />))}
|
||||
</ul>
|
||||
@@ -53,7 +53,7 @@ function CategoryItem({ category, active, onClick }: CategoryItemProps) {
|
||||
)}
|
||||
<AppCategoryLabel
|
||||
category={category}
|
||||
className={cn('system-sm-medium text-components-menu-item-text group-hover:text-components-menu-item-text-hover group-[.active]:text-components-menu-item-text-active', active && 'system-sm-semibold')}
|
||||
className={cn('text-components-menu-item-text system-sm-medium group-hover:text-components-menu-item-text-hover group-[.active]:text-components-menu-item-text-active', active && 'system-sm-semibold')}
|
||||
/>
|
||||
</li>
|
||||
)
|
||||
|
||||
@@ -117,10 +117,10 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }:
|
||||
<div className="px-10">
|
||||
<div className="h-6 w-full 2xl:h-[139px]" />
|
||||
<div className="pb-6 pt-1">
|
||||
<span className="title-2xl-semi-bold text-text-primary">{t('newApp.startFromBlank', { ns: 'app' })}</span>
|
||||
<span className="text-text-primary title-2xl-semi-bold">{t('newApp.startFromBlank', { ns: 'app' })}</span>
|
||||
</div>
|
||||
<div className="mb-2 leading-6">
|
||||
<span className="system-sm-semibold text-text-secondary">{t('newApp.chooseAppType', { ns: 'app' })}</span>
|
||||
<span className="text-text-secondary system-sm-semibold">{t('newApp.chooseAppType', { ns: 'app' })}</span>
|
||||
</div>
|
||||
<div className="flex w-[660px] flex-col gap-4">
|
||||
<div>
|
||||
@@ -160,7 +160,7 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }:
|
||||
className="flex cursor-pointer items-center border-0 bg-transparent p-0"
|
||||
onClick={() => setIsAppTypeExpanded(!isAppTypeExpanded)}
|
||||
>
|
||||
<span className="system-2xs-medium-uppercase text-text-tertiary">{t('newApp.forBeginners', { ns: 'app' })}</span>
|
||||
<span className="text-text-tertiary system-2xs-medium-uppercase">{t('newApp.forBeginners', { ns: 'app' })}</span>
|
||||
<RiArrowRightSLine className={`ml-1 h-4 w-4 text-text-tertiary transition-transform ${isAppTypeExpanded ? 'rotate-90' : ''}`} />
|
||||
</button>
|
||||
</div>
|
||||
@@ -212,7 +212,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="system-sm-semibold text-text-secondary">{t('newApp.captionName', { ns: 'app' })}</label>
|
||||
<label className="text-text-secondary system-sm-semibold">{t('newApp.captionName', { ns: 'app' })}</label>
|
||||
</div>
|
||||
<Input
|
||||
value={name}
|
||||
@@ -243,8 +243,8 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }:
|
||||
</div>
|
||||
<div>
|
||||
<div className="mb-1 flex h-6 items-center">
|
||||
<label className="system-sm-semibold text-text-secondary">{t('newApp.captionDescription', { ns: 'app' })}</label>
|
||||
<span className="system-xs-regular ml-1 text-text-tertiary">
|
||||
<label className="text-text-secondary system-sm-semibold">{t('newApp.captionDescription', { ns: 'app' })}</label>
|
||||
<span className="ml-1 text-text-tertiary system-xs-regular">
|
||||
(
|
||||
{t('newApp.optional', { ns: 'app' })}
|
||||
)
|
||||
@@ -260,7 +260,7 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }:
|
||||
</div>
|
||||
{isAppsFull && <AppsFull className="mt-4" loc="app-create" />}
|
||||
<div className="flex items-center justify-between pb-10 pt-5">
|
||||
<div className="system-xs-regular flex cursor-pointer items-center gap-1 text-text-tertiary" onClick={onCreateFromTemplate}>
|
||||
<div className="flex cursor-pointer items-center gap-1 text-text-tertiary system-xs-regular" onClick={onCreateFromTemplate}>
|
||||
<span>{t('newApp.noIdeaTip', { ns: 'app' })}</span>
|
||||
<div className="p-[1px]">
|
||||
<RiArrowRightLine className="h-3.5 w-3.5" />
|
||||
@@ -334,8 +334,8 @@ function AppTypeCard({ icon, title, description, active, onClick }: AppTypeCardP
|
||||
onClick={onClick}
|
||||
>
|
||||
{icon}
|
||||
<div className="system-sm-semibold mb-0.5 mt-2 text-text-secondary">{title}</div>
|
||||
<div className="system-xs-regular line-clamp-2 text-text-tertiary" title={description}>{description}</div>
|
||||
<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>
|
||||
)
|
||||
}
|
||||
@@ -367,8 +367,8 @@ function AppPreview({ mode }: { mode: AppModeEnum }) {
|
||||
const previewInfo = modeToPreviewInfoMap[mode]
|
||||
return (
|
||||
<div className="px-8 py-4">
|
||||
<h4 className="system-sm-semibold-uppercase text-text-secondary">{previewInfo.title}</h4>
|
||||
<div className="system-xs-regular mt-1 min-h-8 max-w-96 text-text-tertiary">
|
||||
<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">
|
||||
<span>{previewInfo.description}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -26,8 +26,8 @@ const DSLConfirmModal = ({
|
||||
className="w-[480px]"
|
||||
>
|
||||
<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="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>{t('newApp.appCreateDSLErrorPart1', { ns: 'app' })}</div>
|
||||
<div>{t('newApp.appCreateDSLErrorPart2', { ns: 'app' })}</div>
|
||||
<br />
|
||||
|
||||
@@ -232,7 +232,7 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS
|
||||
isShow={show}
|
||||
onClose={noop}
|
||||
>
|
||||
<div className="title-2xl-semi-bold flex items-center justify-between pb-3 pl-6 pr-5 pt-6 text-text-primary">
|
||||
<div className="flex items-center justify-between pb-3 pl-6 pr-5 pt-6 text-text-primary title-2xl-semi-bold">
|
||||
{t('importFromDSL', { ns: 'app' })}
|
||||
<div
|
||||
className="flex h-8 w-8 cursor-pointer items-center"
|
||||
@@ -241,7 +241,7 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS
|
||||
<RiCloseLine className="h-5 w-5 text-text-tertiary" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="system-md-semibold flex h-9 items-center space-x-6 border-b border-divider-subtle px-6 text-text-tertiary">
|
||||
<div className="flex h-9 items-center space-x-6 border-b border-divider-subtle px-6 text-text-tertiary system-md-semibold">
|
||||
{
|
||||
tabs.map(tab => (
|
||||
<div
|
||||
@@ -275,7 +275,7 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS
|
||||
{
|
||||
currentTab === CreateFromDSLModalTab.FROM_URL && (
|
||||
<div>
|
||||
<div className="system-md-semibold mb-1 text-text-secondary">DSL URL</div>
|
||||
<div className="mb-1 text-text-secondary system-md-semibold">DSL URL</div>
|
||||
<Input
|
||||
placeholder={t('importFromDSLUrlPlaceholder', { ns: 'app' }) || ''}
|
||||
value={dslUrlValue}
|
||||
@@ -309,8 +309,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="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="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>{t('newApp.appCreateDSLErrorPart1', { ns: 'app' })}</div>
|
||||
<div>{t('newApp.appCreateDSLErrorPart2', { ns: 'app' })}</div>
|
||||
<br />
|
||||
|
||||
@@ -121,7 +121,7 @@ const Uploader: FC<Props> = ({
|
||||
</div>
|
||||
)}
|
||||
{file && (
|
||||
<div className={cn('group flex items-center rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg shadow-xs', ' hover:bg-components-panel-on-panel-item-bg-hover')}>
|
||||
<div className={cn('group flex items-center rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg shadow-xs', 'hover:bg-components-panel-on-panel-item-bg-hover')}>
|
||||
<div className="flex items-center justify-center p-3">
|
||||
<YamlIcon className="h-6 w-6 shrink-0" />
|
||||
</div>
|
||||
|
||||
@@ -80,8 +80,8 @@ const DuplicateAppModal = ({
|
||||
<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="mb-9 text-text-secondary system-sm-regular">
|
||||
<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"
|
||||
|
||||
@@ -28,11 +28,11 @@ const EmptyElement: FC<{ appDetail: App }> = ({ appDetail }) => {
|
||||
return (
|
||||
<div className="flex h-full items-center justify-center">
|
||||
<div className="box-border h-fit w-[560px] rounded-2xl bg-background-section-burn px-5 py-4">
|
||||
<span className="system-md-semibold text-text-secondary">
|
||||
<span className="text-text-secondary system-md-semibold">
|
||||
{t('table.empty.element.title', { ns: 'appLog' })}
|
||||
<ThreeDotsIcon className="relative -left-1.5 -top-3 inline text-text-secondary" />
|
||||
</span>
|
||||
<div className="system-sm-regular mt-2 text-text-tertiary">
|
||||
<div className="mt-2 text-text-tertiary system-sm-regular">
|
||||
<Trans
|
||||
i18nKey="table.empty.element.content"
|
||||
ns="appLog"
|
||||
|
||||
@@ -118,7 +118,7 @@ const Logs: FC<ILogsProps> = ({ appDetail }) => {
|
||||
|
||||
return (
|
||||
<div className="flex h-full grow flex-col">
|
||||
<p className="system-sm-regular shrink-0 text-text-tertiary">{t('description', { ns: 'appLog' })}</p>
|
||||
<p className="shrink-0 text-text-tertiary system-sm-regular">{t('description', { ns: 'appLog' })}</p>
|
||||
<div className="flex max-h-[calc(100%-16px)] flex-1 grow flex-col py-4">
|
||||
<Filter isChatMode={isChatMode} appId={appDetail.id} queryParams={queryParams} setQueryParams={handleQueryParamsChange} />
|
||||
{total === undefined
|
||||
|
||||
@@ -96,7 +96,7 @@ const statusTdRender = (statusCount: StatusCount) => {
|
||||
|
||||
if (statusCount.paused > 0) {
|
||||
return (
|
||||
<div className="system-xs-semibold-uppercase inline-flex items-center gap-1">
|
||||
<div className="inline-flex items-center gap-1 system-xs-semibold-uppercase">
|
||||
<Indicator color="yellow" />
|
||||
<span className="text-util-colors-warning-warning-600">Pending</span>
|
||||
</div>
|
||||
@@ -104,7 +104,7 @@ const statusTdRender = (statusCount: StatusCount) => {
|
||||
}
|
||||
else if (statusCount.partial_success + statusCount.failed === 0) {
|
||||
return (
|
||||
<div className="system-xs-semibold-uppercase inline-flex items-center gap-1">
|
||||
<div className="inline-flex items-center gap-1 system-xs-semibold-uppercase">
|
||||
<Indicator color="green" />
|
||||
<span className="text-util-colors-green-green-600">Success</span>
|
||||
</div>
|
||||
@@ -112,7 +112,7 @@ const statusTdRender = (statusCount: StatusCount) => {
|
||||
}
|
||||
else if (statusCount.failed === 0) {
|
||||
return (
|
||||
<div className="system-xs-semibold-uppercase inline-flex items-center gap-1">
|
||||
<div className="inline-flex items-center gap-1 system-xs-semibold-uppercase">
|
||||
<Indicator color="green" />
|
||||
<span className="text-util-colors-green-green-600">Partial Success</span>
|
||||
</div>
|
||||
@@ -120,7 +120,7 @@ const statusTdRender = (statusCount: StatusCount) => {
|
||||
}
|
||||
else {
|
||||
return (
|
||||
<div className="system-xs-semibold-uppercase inline-flex items-center gap-1">
|
||||
<div className="inline-flex items-center gap-1 system-xs-semibold-uppercase">
|
||||
<Indicator color="red" />
|
||||
<span className="text-util-colors-red-red-600">
|
||||
{statusCount.failed}
|
||||
@@ -562,9 +562,9 @@ function DetailPanel({ detail, onFeedback }: IDetailPanel) {
|
||||
{/* Panel Header */}
|
||||
<div className="flex shrink-0 items-center gap-2 rounded-t-xl bg-components-panel-bg pb-2 pl-4 pr-3 pt-3">
|
||||
<div className="shrink-0">
|
||||
<div className="system-xs-semibold-uppercase mb-0.5 text-text-primary">{isChatMode ? t('detail.conversationId', { ns: 'appLog' }) : t('detail.time', { ns: 'appLog' })}</div>
|
||||
<div className="mb-0.5 text-text-primary system-xs-semibold-uppercase">{isChatMode ? t('detail.conversationId', { ns: 'appLog' }) : t('detail.time', { ns: 'appLog' })}</div>
|
||||
{isChatMode && (
|
||||
<div className="system-2xs-regular-uppercase flex items-center text-text-secondary">
|
||||
<div className="flex items-center text-text-secondary system-2xs-regular-uppercase">
|
||||
<Tooltip
|
||||
popupContent={detail.id}
|
||||
>
|
||||
@@ -574,7 +574,7 @@ function DetailPanel({ detail, onFeedback }: IDetailPanel) {
|
||||
</div>
|
||||
)}
|
||||
{!isChatMode && (
|
||||
<div className="system-2xs-regular-uppercase text-text-secondary">{formatTime(detail.created_at, t('dateTimeFormat', { ns: 'appLog' }) as string)}</div>
|
||||
<div className="text-text-secondary system-2xs-regular-uppercase">{formatTime(detail.created_at, t('dateTimeFormat', { ns: 'appLog' }) as string)}</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex grow flex-wrap items-center justify-end gap-y-1">
|
||||
@@ -600,7 +600,7 @@ function DetailPanel({ detail, onFeedback }: IDetailPanel) {
|
||||
? (
|
||||
<div className="px-6 py-4">
|
||||
<div className="flex h-[18px] items-center space-x-3">
|
||||
<div className="system-xs-semibold-uppercase text-text-tertiary">{t('table.header.output', { ns: 'appLog' })}</div>
|
||||
<div className="text-text-tertiary system-xs-semibold-uppercase">{t('table.header.output', { ns: 'appLog' })}</div>
|
||||
<div
|
||||
className="h-px grow"
|
||||
style={{
|
||||
@@ -692,7 +692,7 @@ function DetailPanel({ detail, onFeedback }: IDetailPanel) {
|
||||
</div>
|
||||
{hasMore && (
|
||||
<div className="py-3 text-center">
|
||||
<div className="system-xs-regular text-text-tertiary">
|
||||
<div className="text-text-tertiary system-xs-regular">
|
||||
{t('detail.loading', { ns: 'appLog' })}
|
||||
...
|
||||
</div>
|
||||
@@ -950,7 +950,7 @@ const ConversationList: FC<IConversationList> = ({ logs, appDetail, onRefresh })
|
||||
)}
|
||||
popupClassName={(isHighlight && !isChatMode) ? '' : '!hidden'}
|
||||
>
|
||||
<div className={cn(isEmptyStyle ? 'text-text-quaternary' : 'text-text-secondary', !isHighlight ? '' : 'bg-orange-100', 'system-sm-regular overflow-hidden text-ellipsis whitespace-nowrap')}>
|
||||
<div className={cn(isEmptyStyle ? 'text-text-quaternary' : 'text-text-secondary', !isHighlight ? '' : 'bg-orange-100', 'overflow-hidden text-ellipsis whitespace-nowrap system-sm-regular')}>
|
||||
{value || '-'}
|
||||
</div>
|
||||
</Tooltip>
|
||||
@@ -963,7 +963,7 @@ const ConversationList: FC<IConversationList> = ({ logs, appDetail, onRefresh })
|
||||
return (
|
||||
<div className="relative mt-2 grow overflow-x-auto">
|
||||
<table className={cn('w-full min-w-[440px] border-collapse border-0')}>
|
||||
<thead className="system-xs-medium-uppercase text-text-tertiary">
|
||||
<thead className="text-text-tertiary system-xs-medium-uppercase">
|
||||
<tr>
|
||||
<td className="w-5 whitespace-nowrap rounded-l-lg bg-background-section-burn pl-2 pr-1"></td>
|
||||
<td className="whitespace-nowrap bg-background-section-burn py-1.5 pl-3">{isChatMode ? t('table.header.summary', { ns: 'appLog' }) : t('table.header.input', { ns: 'appLog' })}</td>
|
||||
@@ -976,7 +976,7 @@ const ConversationList: FC<IConversationList> = ({ logs, appDetail, onRefresh })
|
||||
<td className="whitespace-nowrap rounded-r-lg bg-background-section-burn py-1.5 pl-3">{t('table.header.time', { ns: 'appLog' })}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="system-sm-regular text-text-secondary">
|
||||
<tbody className="text-text-secondary system-sm-regular">
|
||||
{logs.data.map((log: any) => {
|
||||
const endUser = log.from_end_user_session_id || log.from_account_name
|
||||
const leftValue = get(log, isChatMode ? 'name' : 'message.inputs.query') || (!isChatMode ? (get(log, 'message.query') || get(log, 'message.inputs.default_input')) : '') || ''
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user