From 4d465d6cf93f7c66aac60f58f0a808740b369dbe Mon Sep 17 00:00:00 2001 From: yyh Date: Fri, 23 Jan 2026 14:22:58 +0800 Subject: [PATCH] feat(skill-editor): implement StartTabContent with modular component structure Refactor StartTabContent into separate components following Figma design specs: - ActionCard: reusable card with icon, title, description - SectionHeader: title/xl-semi-bold header with description - CreateImportSection: 3-column grid layout for Create/Import cards - SkillTemplatesSection: templates area with placeholder Align styles with Figma: 3-col grid, 16px title, proper spacing and padding. Add i18n translations for all user-facing text (en-US, zh-Hans). --- .../workflow/skill/file-content-panel.tsx | 2 +- .../workflow/skill/start-tab-content.tsx | 23 --------- .../workflow/skill/start-tab/action-card.tsx | 49 +++++++++++++++++++ .../skill/start-tab/create-import-section.tsx | 28 +++++++++++ .../workflow/skill/start-tab/index.tsx | 17 +++++++ .../skill/start-tab/section-header.tsx | 27 ++++++++++ .../start-tab/skill-templates-section.tsx | 26 ++++++++++ web/i18n/en-US/workflow.json | 7 +++ web/i18n/zh-Hans/workflow.json | 7 +++ 9 files changed, 162 insertions(+), 24 deletions(-) delete mode 100644 web/app/components/workflow/skill/start-tab-content.tsx create mode 100644 web/app/components/workflow/skill/start-tab/action-card.tsx create mode 100644 web/app/components/workflow/skill/start-tab/create-import-section.tsx create mode 100644 web/app/components/workflow/skill/start-tab/index.tsx create mode 100644 web/app/components/workflow/skill/start-tab/section-header.tsx create mode 100644 web/app/components/workflow/skill/start-tab/skill-templates-section.tsx diff --git a/web/app/components/workflow/skill/file-content-panel.tsx b/web/app/components/workflow/skill/file-content-panel.tsx index 6ffc65c675..e89b865ea9 100644 --- a/web/app/components/workflow/skill/file-content-panel.tsx +++ b/web/app/components/workflow/skill/file-content-panel.tsx @@ -20,7 +20,7 @@ import { useFileTypeInfo } from './hooks/use-file-type-info' import { useSkillAssetNodeMap } from './hooks/use-skill-asset-tree' import { useSkillFileData } from './hooks/use-skill-file-data' import { useSkillFileSave } from './hooks/use-skill-file-save' -import StartTabContent from './start-tab-content' +import StartTabContent from './start-tab' import { getFileLanguage } from './utils/file-utils' import MediaFilePreview from './viewer/media-file-preview' import UnsupportedFileDownload from './viewer/unsupported-file-download' diff --git a/web/app/components/workflow/skill/start-tab-content.tsx b/web/app/components/workflow/skill/start-tab-content.tsx deleted file mode 100644 index 5b8ccf2291..0000000000 --- a/web/app/components/workflow/skill/start-tab-content.tsx +++ /dev/null @@ -1,23 +0,0 @@ -'use client' - -import type { FC } from 'react' -import * as React from 'react' -import Home from '@/app/components/base/icons/src/vender/workflow/Home' - -// TODO: use translations -const StartTabContent: FC = () => { - return ( -
-
-
- -
- - Coming soon... - -
-
- ) -} - -export default React.memo(StartTabContent) diff --git a/web/app/components/workflow/skill/start-tab/action-card.tsx b/web/app/components/workflow/skill/start-tab/action-card.tsx new file mode 100644 index 0000000000..654092b1b1 --- /dev/null +++ b/web/app/components/workflow/skill/start-tab/action-card.tsx @@ -0,0 +1,49 @@ +'use client' + +import type { FC, ReactNode } from 'react' +import { memo } from 'react' +import { cn } from '@/utils/classnames' + +type ActionCardProps = { + icon: ReactNode + title: string + description: string + onClick?: () => void +} + +const ActionCard: FC = ({ + icon, + title, + description, + onClick, +}) => { + return ( + + ) +} + +export default memo(ActionCard) diff --git a/web/app/components/workflow/skill/start-tab/create-import-section.tsx b/web/app/components/workflow/skill/start-tab/create-import-section.tsx new file mode 100644 index 0000000000..2278f4fae0 --- /dev/null +++ b/web/app/components/workflow/skill/start-tab/create-import-section.tsx @@ -0,0 +1,28 @@ +'use client' + +import type { FC } from 'react' +import { RiAddCircleFill, RiUploadLine } from '@remixicon/react' +import { memo } from 'react' +import { useTranslation } from 'react-i18next' +import ActionCard from './action-card' + +const CreateImportSection: FC = () => { + const { t } = useTranslation('workflow') + + return ( +
+ } + title={t('skill.startTab.createBlankSkill')} + description={t('skill.startTab.createBlankSkillDesc')} + /> + } + title={t('skill.startTab.importSkill')} + description={t('skill.startTab.importSkillDesc')} + /> +
+ ) +} + +export default memo(CreateImportSection) diff --git a/web/app/components/workflow/skill/start-tab/index.tsx b/web/app/components/workflow/skill/start-tab/index.tsx new file mode 100644 index 0000000000..2ff8be87e2 --- /dev/null +++ b/web/app/components/workflow/skill/start-tab/index.tsx @@ -0,0 +1,17 @@ +'use client' + +import type { FC } from 'react' +import { memo } from 'react' +import CreateImportSection from './create-import-section' +import SkillTemplatesSection from './skill-templates-section' + +const StartTabContent: FC = () => { + return ( +
+ + +
+ ) +} + +export default memo(StartTabContent) diff --git a/web/app/components/workflow/skill/start-tab/section-header.tsx b/web/app/components/workflow/skill/start-tab/section-header.tsx new file mode 100644 index 0000000000..654da5127c --- /dev/null +++ b/web/app/components/workflow/skill/start-tab/section-header.tsx @@ -0,0 +1,27 @@ +'use client' + +import type { FC } from 'react' +import { memo } from 'react' + +type SectionHeaderProps = { + title: string + description: string +} + +const SectionHeader: FC = ({ + title, + description, +}) => { + return ( +
+

+ {title} +

+

+ {description} +

+
+ ) +} + +export default memo(SectionHeader) diff --git a/web/app/components/workflow/skill/start-tab/skill-templates-section.tsx b/web/app/components/workflow/skill/start-tab/skill-templates-section.tsx new file mode 100644 index 0000000000..e306581fb3 --- /dev/null +++ b/web/app/components/workflow/skill/start-tab/skill-templates-section.tsx @@ -0,0 +1,26 @@ +'use client' + +import type { FC } from 'react' +import { memo } from 'react' +import { useTranslation } from 'react-i18next' +import SectionHeader from './section-header' + +const SkillTemplatesSection: FC = () => { + const { t } = useTranslation('workflow') + + return ( +
+ +
+ + {t('skill.startTab.templatesComingSoon')} + +
+
+ ) +} + +export default memo(SkillTemplatesSection) diff --git a/web/i18n/en-US/workflow.json b/web/i18n/en-US/workflow.json index 9d84328957..09bf1b81d9 100644 --- a/web/i18n/en-US/workflow.json +++ b/web/i18n/en-US/workflow.json @@ -1031,6 +1031,13 @@ "singleRun.testRun": "Test Run", "singleRun.testRunIteration": "Test Run Iteration", "singleRun.testRunLoop": "Test Run Loop", + "skill.startTab.createBlankSkill": "Create Blank Skill", + "skill.startTab.createBlankSkillDesc": "Start with an empty folder structure", + "skill.startTab.importSkill": "Import Skill", + "skill.startTab.importSkillDesc": "Import skill from skill.zip file", + "skill.startTab.templatesComingSoon": "Templates coming soon…", + "skill.startTab.templatesDesc": "Choose a template to bootstrap your agent's capabilities", + "skill.startTab.templatesTitle": "Skill Templates", "skillEditor.authorizationRequired": "Authorization required before use.", "skillEditor.previewUnavailable": "Preview unavailable", "skillEditor.referenceFiles": "Reference files", diff --git a/web/i18n/zh-Hans/workflow.json b/web/i18n/zh-Hans/workflow.json index 9676a50d07..82e9fa6a42 100644 --- a/web/i18n/zh-Hans/workflow.json +++ b/web/i18n/zh-Hans/workflow.json @@ -1023,6 +1023,13 @@ "singleRun.testRun": "测试运行", "singleRun.testRunIteration": "测试运行迭代", "singleRun.testRunLoop": "测试运行循环", + "skill.startTab.createBlankSkill": "创建空白 Skill", + "skill.startTab.createBlankSkillDesc": "从空文件夹结构开始", + "skill.startTab.importSkill": "导入 Skill", + "skill.startTab.importSkillDesc": "从 skill.zip 文件导入", + "skill.startTab.templatesComingSoon": "模板即将推出…", + "skill.startTab.templatesDesc": "选择模板来快速构建你的 Agent 能力", + "skill.startTab.templatesTitle": "Skill 模板", "skillEditor.authorizationRequired": "使用前需要授权。", "skillEditor.previewUnavailable": "无法预览", "skillEditor.referenceFiles": "引用文件",