From cb209bc04938b70091bc73638014f0ad5c7069ab Mon Sep 17 00:00:00 2001 From: Joel Date: Mon, 13 Jul 2026 15:52:12 +0800 Subject: [PATCH] chore: add skill upload fail tip (#38851) --- .../skills/__tests__/index.spec.tsx | 54 +++++++++++++++++++ .../orchestrate/skills/upload-dialog.tsx | 38 ++++++++++++- web/i18n/ar-TN/agent-v-2.json | 2 + web/i18n/de-DE/agent-v-2.json | 2 + web/i18n/en-US/agent-v-2.json | 2 + web/i18n/es-ES/agent-v-2.json | 2 + web/i18n/fa-IR/agent-v-2.json | 2 + web/i18n/fr-FR/agent-v-2.json | 2 + web/i18n/hi-IN/agent-v-2.json | 2 + web/i18n/id-ID/agent-v-2.json | 2 + web/i18n/it-IT/agent-v-2.json | 2 + web/i18n/ja-JP/agent-v-2.json | 2 + web/i18n/ko-KR/agent-v-2.json | 2 + web/i18n/nl-NL/agent-v-2.json | 2 + web/i18n/pl-PL/agent-v-2.json | 2 + web/i18n/pt-BR/agent-v-2.json | 2 + web/i18n/ro-RO/agent-v-2.json | 2 + web/i18n/ru-RU/agent-v-2.json | 2 + web/i18n/sl-SI/agent-v-2.json | 2 + web/i18n/th-TH/agent-v-2.json | 2 + web/i18n/tr-TR/agent-v-2.json | 2 + web/i18n/uk-UA/agent-v-2.json | 2 + web/i18n/vi-VN/agent-v-2.json | 2 + web/i18n/zh-Hans/agent-v-2.json | 2 + web/i18n/zh-Hant/agent-v-2.json | 2 + 25 files changed, 136 insertions(+), 2 deletions(-) diff --git a/web/features/agent-v2/agent-detail/configure/components/orchestrate/skills/__tests__/index.spec.tsx b/web/features/agent-v2/agent-detail/configure/components/orchestrate/skills/__tests__/index.spec.tsx index e279d75e9c2..f54b412a051 100644 --- a/web/features/agent-v2/agent-detail/configure/components/orchestrate/skills/__tests__/index.spec.tsx +++ b/web/features/agent-v2/agent-detail/configure/components/orchestrate/skills/__tests__/index.spec.tsx @@ -343,6 +343,60 @@ describe('AgentSkills', () => { expect(toast.success).toHaveBeenCalled() }) + it('should hide skill package guidance before an upload fails', async () => { + const user = userEvent.setup() + renderAgentSkills({ initialDraft: defaultAgentSoulConfigFormState }) + + await user.click( + screen.getByRole('button', { name: /agentV2\.agentDetail\.configure\.skills\.add/i }), + ) + + expect( + screen.queryByText('agentV2.agentDetail.configure.skills.upload.warning.specification'), + ).not.toBeInTheDocument() + }) + + it('should show skill package guidance after failure and hide it when retrying', async () => { + const user = userEvent.setup() + mocks.uploadSkillMutationFn + .mockRejectedValueOnce(new Error('Backend upload error')) + .mockImplementationOnce(() => new Promise(() => undefined)) + renderAgentSkills({ initialDraft: defaultAgentSoulConfigFormState }) + + await user.click( + screen.getByRole('button', { name: /agentV2\.agentDetail\.configure\.skills\.add/i }), + ) + const input = await waitFor(() => { + const element = document.querySelector('input[type="file"]') + expect(element).not.toBeNull() + return element as HTMLInputElement + }) + await user.upload( + input, + new File(['skill'], 'invoice-helper.skill', { type: 'application/zip' }), + ) + const uploadButton = screen.getByRole('button', { + name: /agentDetail\.configure\.skills\.upload\.action/i, + }) + + await user.click(uploadButton) + + expect( + await screen.findByText('agentV2.agentDetail.configure.skills.upload.warning.files'), + ).toBeInTheDocument() + expect( + screen.getByText('agentV2.agentDetail.configure.skills.upload.warning.specification'), + ).toBeInTheDocument() + + await user.click(uploadButton) + + await waitFor(() => { + expect( + screen.queryByText('agentV2.agentDetail.configure.skills.upload.warning.files'), + ).not.toBeInTheDocument() + }) + }) + it('should not show the frontend fallback error when skill upload fails', async () => { const user = userEvent.setup() mocks.uploadSkillMutationFn.mockRejectedValueOnce(new Error('Backend upload error')) diff --git a/web/features/agent-v2/agent-detail/configure/components/orchestrate/skills/upload-dialog.tsx b/web/features/agent-v2/agent-detail/configure/components/orchestrate/skills/upload-dialog.tsx index 04c66403747..58c87641b6e 100644 --- a/web/features/agent-v2/agent-detail/configure/components/orchestrate/skills/upload-dialog.tsx +++ b/web/features/agent-v2/agent-detail/configure/components/orchestrate/skills/upload-dialog.tsx @@ -17,8 +17,9 @@ import { import { toast } from '@langgenius/dify-ui/toast' import { useMutation } from '@tanstack/react-query' import { useRef, useState } from 'react' -import { useTranslation } from 'react-i18next' +import { Trans, useTranslation } from 'react-i18next' import ActionButton from '@/app/components/base/action-button' +import Link from '@/next/link' import { consoleQuery } from '@/service/client' import { formatFileSize } from '@/utils/format' @@ -60,9 +61,11 @@ function hasDraggedFiles(event: DragEvent) { function AgentSkillPackageUploader({ file, onChange, + showWarning, }: { file?: File onChange: (file?: File) => void + showWarning: boolean }) { const { t } = useTranslation('agentV2') const fileInputRef = useRef(null) @@ -183,6 +186,33 @@ function AgentSkillPackageUploader({ )} + {showWarning && ( +
+ +
    +
  • + $['agentDetail.configure.skills.upload.warning.specification']} + ns="agentV2" + components={{ + specificationLink: ( + + ), + }} + /> +
  • +
  • {t(($) => $['agentDetail.configure.skills.upload.warning.files'])}
  • +
+
+ )} ) } @@ -283,7 +313,11 @@ export function AgentSkillUploadDialog({ {t(($) => $['agentDetail.configure.skills.upload.description'])} - +