mirror of
https://github.com/langgenius/dify.git
synced 2026-01-24 12:42:07 +08:00
feat(ui): change runtime selection component
This commit is contained in:
parent
78acfb0040
commit
95d62039b1
@ -1,7 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import type { AppIconSelection } from '../../base/app-icon-picker'
|
||||
import { RiArrowRightLine, RiArrowRightSLine, RiCommandLine, RiCornerDownLeftLine, RiExchange2Fill } from '@remixicon/react'
|
||||
import { RiArrowRightLine, RiArrowRightSLine, RiCheckLine, RiCommandLine, RiCornerDownLeftLine, RiExchange2Fill } from '@remixicon/react'
|
||||
|
||||
import { useDebounceFn, useKeyPress } from 'ahooks'
|
||||
import Image from 'next/image'
|
||||
@ -12,11 +12,13 @@ import { useTranslation } from 'react-i18next'
|
||||
import { useContext } from 'use-context-selector'
|
||||
import { trackEvent } from '@/app/components/base/amplitude'
|
||||
import AppIcon from '@/app/components/base/app-icon'
|
||||
import Badge from '@/app/components/base/badge'
|
||||
import Button from '@/app/components/base/button'
|
||||
import Divider from '@/app/components/base/divider'
|
||||
import FullScreenModal from '@/app/components/base/fullscreen-modal'
|
||||
import { BubbleTextMod, ChatBot, ListSparkle, Logic } from '@/app/components/base/icons/src/vender/solid/communication'
|
||||
import Input from '@/app/components/base/input'
|
||||
import CustomSelect from '@/app/components/base/select/custom'
|
||||
import Textarea from '@/app/components/base/textarea'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import AppsFull from '@/app/components/billing/apps-full-in-dialog'
|
||||
@ -41,6 +43,13 @@ type CreateAppProps = {
|
||||
|
||||
type RuntimeMode = 'classical' | 'new'
|
||||
|
||||
type RuntimeOption = {
|
||||
label: string
|
||||
value: RuntimeMode
|
||||
description: string
|
||||
recommended?: boolean
|
||||
}
|
||||
|
||||
const WORKFLOW_RUNTIME_STORAGE_KEY_PREFIX = 'workflow:sandbox-runtime:'
|
||||
|
||||
function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }: CreateAppProps) {
|
||||
@ -275,45 +284,51 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }:
|
||||
<div className="system-sm-semibold mb-2 text-text-secondary">
|
||||
{t('newApp.runtimeLabel', { ns: 'app' })}
|
||||
</div>
|
||||
<div className="flex gap-3">
|
||||
<button
|
||||
type="button"
|
||||
className={cn(
|
||||
'flex h-10 flex-1 items-center gap-2 rounded-xl border border-components-option-card-option-border bg-components-option-card-option-bg px-3',
|
||||
runtimeMode === 'new' && 'border-components-option-card-option-border-selected bg-components-option-card-option-selected-bg',
|
||||
)}
|
||||
onClick={() => setRuntimeMode('new')}
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
'h-4 w-4 rounded-full border border-components-radio-border bg-components-radio-bg shadow-xs',
|
||||
runtimeMode === 'new' && 'border-[5px] border-components-radio-border-checked',
|
||||
<CustomSelect<RuntimeOption>
|
||||
options={[
|
||||
{
|
||||
label: t('newApp.runtimeOptionNew', { ns: 'app' }),
|
||||
value: 'new',
|
||||
description: t('newApp.runtimeOptionNewDescription', { ns: 'app' }),
|
||||
recommended: true,
|
||||
},
|
||||
{
|
||||
label: t('newApp.runtimeOptionClassical', { ns: 'app' }),
|
||||
value: 'classical',
|
||||
description: t('newApp.runtimeOptionClassicalDescription', { ns: 'app' }),
|
||||
},
|
||||
]}
|
||||
value={runtimeMode}
|
||||
onChange={value => setRuntimeMode(value as RuntimeMode)}
|
||||
triggerProps={{
|
||||
className: '!h-8 !rounded-lg !bg-components-input-bg-normal !px-2 !py-1',
|
||||
}}
|
||||
popupProps={{
|
||||
wrapperClassName: 'z-[60]',
|
||||
className: 'w-full',
|
||||
itemClassName: '!h-auto !py-2 !items-start',
|
||||
}}
|
||||
CustomOption={(option, selected) => (
|
||||
<>
|
||||
<RiCheckLine className={cn(
|
||||
'mr-2 h-4 w-4 shrink-0 text-text-accent',
|
||||
!selected && 'opacity-0',
|
||||
)}
|
||||
/>
|
||||
<div className="system-sm-medium text-text-secondary">
|
||||
{t('newApp.runtimeOptionNew', { ns: 'app' })}
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className={cn(
|
||||
'flex h-10 flex-1 items-center gap-2 rounded-xl border border-components-option-card-option-border bg-components-option-card-option-bg px-3',
|
||||
runtimeMode === 'classical' && 'border-components-option-card-option-border-selected bg-components-option-card-option-selected-bg',
|
||||
)}
|
||||
onClick={() => setRuntimeMode('classical')}
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
'h-4 w-4 rounded-full border border-components-radio-border bg-components-radio-bg shadow-xs',
|
||||
runtimeMode === 'classical' && 'border-[5px] border-components-radio-border-checked',
|
||||
)}
|
||||
/>
|
||||
<div className="system-sm-medium text-text-secondary">
|
||||
{t('newApp.runtimeOptionClassical', { ns: 'app' })}
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
/>
|
||||
<div className="flex flex-1 flex-col gap-0.5">
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="system-sm-semibold text-text-secondary">{option.label}</span>
|
||||
{option.recommended && (
|
||||
<Badge className="!h-4 !px-1">
|
||||
{t('newApp.recommended', { ns: 'app' })}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
<span className="system-xs-regular text-text-tertiary">{option.description}</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@ -174,9 +174,12 @@
|
||||
"newApp.noTemplateFoundTip": "Try searching using different keywords.",
|
||||
"newApp.optional": "Optional",
|
||||
"newApp.previewDemo": "Preview demo",
|
||||
"newApp.recommended": "RECOMMENDED",
|
||||
"newApp.runtimeLabel": "Runtime",
|
||||
"newApp.runtimeOptionClassical": "Classical",
|
||||
"newApp.runtimeOptionNew": "Recommend",
|
||||
"newApp.runtimeOptionClassical": "Classic",
|
||||
"newApp.runtimeOptionClassicalDescription": "Classic runtime for compatibility, without Skill support",
|
||||
"newApp.runtimeOptionNew": "Sandboxed",
|
||||
"newApp.runtimeOptionNewDescription": "Secure runtime with Skill support",
|
||||
"newApp.showTemplates": "I want to choose from a template",
|
||||
"newApp.startFromBlank": "Create from Blank",
|
||||
"newApp.startFromTemplate": "Create from Template",
|
||||
|
||||
@ -173,9 +173,12 @@
|
||||
"newApp.noTemplateFoundTip": "別のキーワードを使用して検索してみてください。",
|
||||
"newApp.optional": "任意",
|
||||
"newApp.previewDemo": "デモをプレビュー",
|
||||
"newApp.runtimeLabel": "Runtime",
|
||||
"newApp.runtimeOptionClassical": "Classical",
|
||||
"newApp.runtimeOptionNew": "推奨",
|
||||
"newApp.recommended": "推奨",
|
||||
"newApp.runtimeLabel": "ランタイム",
|
||||
"newApp.runtimeOptionClassical": "クラシック",
|
||||
"newApp.runtimeOptionClassicalDescription": "互換性のあるクラシックランタイム、Skill非対応",
|
||||
"newApp.runtimeOptionNew": "サンドボックス",
|
||||
"newApp.runtimeOptionNewDescription": "Skill対応のセキュアランタイム",
|
||||
"newApp.showTemplates": "テンプレートから選択したい",
|
||||
"newApp.startFromBlank": "最初から作成",
|
||||
"newApp.startFromTemplate": "テンプレートから作成",
|
||||
|
||||
@ -173,9 +173,12 @@
|
||||
"newApp.noTemplateFoundTip": "请尝试使用不同的关键字进行搜索。",
|
||||
"newApp.optional": "可选",
|
||||
"newApp.previewDemo": "预览 Demo",
|
||||
"newApp.runtimeLabel": "Runtime",
|
||||
"newApp.runtimeOptionClassical": "Classical",
|
||||
"newApp.runtimeOptionNew": "推荐",
|
||||
"newApp.recommended": "推荐",
|
||||
"newApp.runtimeLabel": "运行时",
|
||||
"newApp.runtimeOptionClassical": "经典版",
|
||||
"newApp.runtimeOptionClassicalDescription": "经典运行时,兼容性好,不支持 Skill",
|
||||
"newApp.runtimeOptionNew": "沙箱版",
|
||||
"newApp.runtimeOptionNewDescription": "安全运行时,支持 Skill",
|
||||
"newApp.showTemplates": "我想从范例模板中选择",
|
||||
"newApp.startFromBlank": "创建空白应用",
|
||||
"newApp.startFromTemplate": "从应用模板创建",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user