mirror of
https://github.com/langgenius/dify.git
synced 2026-09-21 13:20:52 +08:00
chore: add skill upload fail tip (#38851)
This commit is contained in:
+54
@@ -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<never>(() => 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'))
|
||||
|
||||
+36
-2
@@ -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<HTMLDivElement>) {
|
||||
function AgentSkillPackageUploader({
|
||||
file,
|
||||
onChange,
|
||||
showWarning,
|
||||
}: {
|
||||
file?: File
|
||||
onChange: (file?: File) => void
|
||||
showWarning: boolean
|
||||
}) {
|
||||
const { t } = useTranslation('agentV2')
|
||||
const fileInputRef = useRef<HTMLInputElement>(null)
|
||||
@@ -183,6 +186,33 @@ function AgentSkillPackageUploader({
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{showWarning && (
|
||||
<div className="mt-2 flex items-start gap-2 rounded-lg border-[0.5px] border-components-badge-status-light-warning-halo bg-state-warning-hover px-3 py-2.5">
|
||||
<span
|
||||
aria-hidden
|
||||
className="mt-0.5 i-ri-alert-fill size-4 shrink-0 text-text-warning-secondary"
|
||||
/>
|
||||
<ul className="list-disc space-y-1 pl-4 system-xs-regular text-text-warning">
|
||||
<li>
|
||||
<Trans
|
||||
i18nKey={($) => $['agentDetail.configure.skills.upload.warning.specification']}
|
||||
ns="agentV2"
|
||||
components={{
|
||||
specificationLink: (
|
||||
<Link
|
||||
href="https://agentskills.io/specification"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="rounded-sm underline outline-hidden focus-visible:ring-2 focus-visible:ring-state-accent-solid"
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</li>
|
||||
<li>{t(($) => $['agentDetail.configure.skills.upload.warning.files'])}</li>
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -283,7 +313,11 @@ export function AgentSkillUploadDialog({
|
||||
<DialogDescription className="mt-1 system-sm-regular text-text-tertiary">
|
||||
{t(($) => $['agentDetail.configure.skills.upload.description'])}
|
||||
</DialogDescription>
|
||||
<AgentSkillPackageUploader file={file} onChange={setFile} />
|
||||
<AgentSkillPackageUploader
|
||||
file={file}
|
||||
onChange={setFile}
|
||||
showWarning={uploadSkillMutation.isError}
|
||||
/>
|
||||
<div className="flex justify-end gap-2 pt-6">
|
||||
<Button
|
||||
type="button"
|
||||
|
||||
Reference in New Issue
Block a user