From 95d62039b1983b7b9350faf582cabda32b21ede9 Mon Sep 17 00:00:00 2001 From: Harry Date: Fri, 9 Jan 2026 18:02:28 +0800 Subject: [PATCH] feat(ui): change runtime selection component --- .../components/app/create-app-modal/index.tsx | 93 +++++++++++-------- web/i18n/en-US/app.json | 7 +- web/i18n/ja-JP/app.json | 9 +- web/i18n/zh-Hans/app.json | 9 +- 4 files changed, 71 insertions(+), 47 deletions(-) diff --git a/web/app/components/app/create-app-modal/index.tsx b/web/app/components/app/create-app-modal/index.tsx index 1ecc386906..4aba40e413 100644 --- a/web/app/components/app/create-app-modal/index.tsx +++ b/web/app/components/app/create-app-modal/index.tsx @@ -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 }:
{t('newApp.runtimeLabel', { ns: 'app' })}
-
- - - -
+ /> +
+
+ {option.label} + {option.recommended && ( + + {t('newApp.recommended', { ns: 'app' })} + + )} +
+ {option.description} +
+ + )} + /> )} diff --git a/web/i18n/en-US/app.json b/web/i18n/en-US/app.json index 043bdcecd6..fe3e7d24bf 100644 --- a/web/i18n/en-US/app.json +++ b/web/i18n/en-US/app.json @@ -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", diff --git a/web/i18n/ja-JP/app.json b/web/i18n/ja-JP/app.json index 2990f634b6..3d1cdc4403 100644 --- a/web/i18n/ja-JP/app.json +++ b/web/i18n/ja-JP/app.json @@ -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": "テンプレートから作成", diff --git a/web/i18n/zh-Hans/app.json b/web/i18n/zh-Hans/app.json index 7d2cf541d4..47b3c68d94 100644 --- a/web/i18n/zh-Hans/app.json +++ b/web/i18n/zh-Hans/app.json @@ -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": "从应用模板创建",