mirror of
https://github.com/langgenius/dify.git
synced 2026-05-10 05:56:31 +08:00
feat: learn dify
This commit is contained in:
parent
36aebdaa28
commit
374eca2504
@ -216,6 +216,24 @@ describe('AppList', () => {
|
||||
expect(screen.getAllByText('explore.continueWork.editedAt:{"time":"3 minutes ago"}')).toHaveLength(5)
|
||||
expect(screen.getByRole('link', { name: 'explore.continueWork.exploreStudio' })).toHaveAttribute('href', '/apps')
|
||||
})
|
||||
|
||||
it('should render learn dify templates without badges or template metadata', () => {
|
||||
mockExploreData = {
|
||||
categories: ['Writing'],
|
||||
allList: [createApp()],
|
||||
}
|
||||
|
||||
renderAppList()
|
||||
|
||||
expect(screen.getByRole('heading', { name: 'explore.learnDify.title' })).toBeInTheDocument()
|
||||
expect(screen.getByText('Your first Workflow - say hello to AI')).toBeInTheDocument()
|
||||
expect(screen.getByText('Build a working Agent with Workflow')).toBeInTheDocument()
|
||||
expect(screen.getByRole('link', { name: 'explore.learnDify.moreTemplates' })).toHaveAttribute('href', '/explore/apps')
|
||||
expect(screen.queryByText('Run this first')).not.toBeInTheDocument()
|
||||
expect(screen.queryByText('Then try this')).not.toBeInTheDocument()
|
||||
expect(screen.queryByText('workflow')).not.toBeInTheDocument()
|
||||
expect(screen.queryByText('3 min')).not.toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
describe('Props', () => {
|
||||
|
||||
@ -19,6 +19,7 @@ import Banner from '@/app/components/explore/banner/banner'
|
||||
import Category from '@/app/components/explore/category'
|
||||
import ContinueWork from '@/app/components/explore/continue-work'
|
||||
import CreateAppModal from '@/app/components/explore/create-app-modal'
|
||||
import LearnDify from '@/app/components/explore/learn-dify'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import { useImportDSL } from '@/hooks/use-import-dsl'
|
||||
import {
|
||||
@ -193,6 +194,7 @@ const Apps = ({
|
||||
</div>
|
||||
)}
|
||||
<ContinueWork className="mt-10" />
|
||||
<LearnDify className="mt-4" />
|
||||
|
||||
<div className="sticky top-0 z-10 bg-background-body">
|
||||
<div className={cn(
|
||||
|
||||
50
web/app/components/explore/learn-dify/data.ts
Normal file
50
web/app/components/explore/learn-dify/data.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import type { AppIconType } from '@/types/app'
|
||||
|
||||
export type LearnDifyItem = {
|
||||
id: string
|
||||
title: string
|
||||
description: string
|
||||
icon_type: AppIconType | null
|
||||
icon: string
|
||||
icon_background: string | null
|
||||
icon_url: string | null
|
||||
}
|
||||
|
||||
export const learnDifyItems: LearnDifyItem[] = [
|
||||
{
|
||||
id: 'first-workflow',
|
||||
title: 'Your first Workflow - say hello to AI',
|
||||
description: 'Search Notion pages and open visited ones faster. No admin access required.',
|
||||
icon_type: 'emoji',
|
||||
icon: '🤖',
|
||||
icon_background: '#F0FDF9',
|
||||
icon_url: null,
|
||||
},
|
||||
{
|
||||
id: 'agent-with-workflow',
|
||||
title: 'Build a working Agent with Workflow',
|
||||
description: 'Agent node to let your AI call tools and reason - inside a full Workflow you control.',
|
||||
icon_type: 'emoji',
|
||||
icon: '🤖',
|
||||
icon_background: '#F0FDF9',
|
||||
icon_url: null,
|
||||
},
|
||||
{
|
||||
id: 'if-else-logic',
|
||||
title: 'Add logic with If/Else',
|
||||
description: 'Route your workflow down different paths based on conditions.',
|
||||
icon_type: 'emoji',
|
||||
icon: '🤖',
|
||||
icon_background: '#F0FDF9',
|
||||
icon_url: null,
|
||||
},
|
||||
{
|
||||
id: 'customer-support-bot',
|
||||
title: 'Customer support bot',
|
||||
description: 'Auto-reply to common questions using your own knowledge base.',
|
||||
icon_type: 'emoji',
|
||||
icon: '🤖',
|
||||
icon_background: '#F0FDF9',
|
||||
icon_url: null,
|
||||
},
|
||||
]
|
||||
50
web/app/components/explore/learn-dify/index.tsx
Normal file
50
web/app/components/explore/learn-dify/index.tsx
Normal file
@ -0,0 +1,50 @@
|
||||
'use client'
|
||||
|
||||
import { cn } from '@langgenius/dify-ui/cn'
|
||||
import * as React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Link from '@/next/link'
|
||||
import { learnDifyItems } from './data'
|
||||
import LearnDifyItem from './item'
|
||||
|
||||
type LearnDifyProps = {
|
||||
className?: string
|
||||
}
|
||||
|
||||
const LearnDify = ({
|
||||
className,
|
||||
}: LearnDifyProps) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<section className={cn('px-12 pb-6', className)} aria-labelledby="learn-dify-title">
|
||||
<div className="flex min-h-12 items-end justify-between gap-4 pb-2">
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="flex items-center justify-between gap-4">
|
||||
<h2 id="learn-dify-title" className="min-w-0 truncate system-xl-semibold text-text-primary">
|
||||
{t('learnDify.title', { ns: 'explore' })}
|
||||
</h2>
|
||||
<button type="button" className="shrink-0 system-sm-medium text-text-primary">
|
||||
{t('learnDify.hide', { ns: 'explore' })}
|
||||
</button>
|
||||
</div>
|
||||
<div className="mt-1 flex items-center justify-between gap-4">
|
||||
<p className="min-w-0 truncate system-xs-regular text-text-tertiary">
|
||||
{t('learnDify.description', { ns: 'explore' })}
|
||||
</p>
|
||||
<Link href="/explore/apps" className="shrink-0 system-sm-medium text-text-accent">
|
||||
{t('learnDify.moreTemplates', { ns: 'explore' })}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2 xl:grid-cols-4">
|
||||
{learnDifyItems.map(item => (
|
||||
<LearnDifyItem key={item.id} item={item} />
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(LearnDify)
|
||||
35
web/app/components/explore/learn-dify/item.tsx
Normal file
35
web/app/components/explore/learn-dify/item.tsx
Normal file
@ -0,0 +1,35 @@
|
||||
'use client'
|
||||
|
||||
import type { LearnDifyItem as LearnDifyItemData } from './data'
|
||||
import * as React from 'react'
|
||||
import AppIcon from '@/app/components/base/app-icon'
|
||||
|
||||
type LearnDifyItemProps = {
|
||||
item: LearnDifyItemData
|
||||
}
|
||||
|
||||
const LearnDifyItem = ({
|
||||
item,
|
||||
}: LearnDifyItemProps) => {
|
||||
return (
|
||||
<article className="flex min-w-0 flex-col overflow-hidden rounded-xl border-[0.5px] border-components-panel-border-subtle bg-components-panel-on-panel-item-bg px-4 py-3 shadow-md">
|
||||
<div className="flex items-center gap-3">
|
||||
<AppIcon
|
||||
size="large"
|
||||
iconType={item.icon_type}
|
||||
icon={item.icon}
|
||||
background={item.icon_background}
|
||||
imageUrl={item.icon_url}
|
||||
/>
|
||||
<h3 className="line-clamp-2 min-h-10 min-w-0 flex-1 system-md-semibold text-text-secondary" title={item.title}>
|
||||
{item.title}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="mt-3 line-clamp-2 min-h-8 system-xs-regular text-text-tertiary">
|
||||
{item.description}
|
||||
</p>
|
||||
</article>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(LearnDifyItem)
|
||||
@ -23,6 +23,10 @@
|
||||
"continueWork.editedAt": "Edited {{time}}",
|
||||
"continueWork.exploreStudio": "Explore Studio →",
|
||||
"continueWork.title": "Continue work with",
|
||||
"learnDify.description": "Follow the path - or jump to whichever step you're ready for.",
|
||||
"learnDify.hide": "Hide",
|
||||
"learnDify.moreTemplates": "More learning templates →",
|
||||
"learnDify.title": "Learn Dify",
|
||||
"sidebar.action.delete": "Delete",
|
||||
"sidebar.action.pin": "Pin",
|
||||
"sidebar.action.rename": "Rename",
|
||||
|
||||
@ -23,6 +23,10 @@
|
||||
"continueWork.editedAt": "{{time}}编辑",
|
||||
"continueWork.exploreStudio": "探索工作室 →",
|
||||
"continueWork.title": "继续处理",
|
||||
"learnDify.description": "按路径学习,或直接跳到你准备好的步骤。",
|
||||
"learnDify.hide": "隐藏",
|
||||
"learnDify.moreTemplates": "更多学习模板 →",
|
||||
"learnDify.title": "学习 Dify",
|
||||
"sidebar.action.delete": "删除",
|
||||
"sidebar.action.pin": "置顶",
|
||||
"sidebar.action.rename": "重命名",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user