Compare commits
3 Commits
test/real-
...
codex/refa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb6a2c2f75 | ||
|
|
9695fe79f7 | ||
|
|
6e727cf12a |
@@ -1416,7 +1416,7 @@
|
||||
},
|
||||
"web/app/components/base/icons/src/vender/plugin/index.ts": {
|
||||
"no-barrel-files/no-barrel-files": {
|
||||
"count": 3
|
||||
"count": 2
|
||||
}
|
||||
},
|
||||
"web/app/components/base/icons/src/vender/solid/FinanceAndECommerce/index.ts": {
|
||||
@@ -3059,14 +3059,6 @@
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"web/app/components/plugins/marketplace/plugin-type-switch.tsx": {
|
||||
"jsx_a11y/click-events-have-key-events": {
|
||||
"count": 1
|
||||
},
|
||||
"jsx_a11y/no-static-element-interactions": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"web/app/components/plugins/plugin-auth/authorized/index.tsx": {
|
||||
"no-restricted-imports": {
|
||||
"count": 1
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
{
|
||||
"icon": {
|
||||
"type": "element",
|
||||
"isRootNode": true,
|
||||
"name": "svg",
|
||||
"attributes": {
|
||||
"width": "16",
|
||||
"height": "16",
|
||||
"viewBox": "0 0 16 16",
|
||||
"fill": "none",
|
||||
"xmlns": "http://www.w3.org/2000/svg"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"fill-rule": "evenodd",
|
||||
"clip-rule": "evenodd",
|
||||
"d": "M7.1499 6.35213L7.25146 6.38208L14.2248 9.03898L14.3172 9.08195C14.7224 9.30788 14.778 9.87906 14.424 10.179L14.342 10.2389L11.8172 11.817L10.2391 14.3417C9.96271 14.7839 9.32424 14.751 9.08219 14.317L9.03923 14.2245L6.38232 7.25122C6.18829 6.74188 6.64437 6.24196 7.1499 6.35213ZM9.81201 12.5084L10.7671 10.981L10.8114 10.9185C10.8589 10.8589 10.9163 10.8075 10.9813 10.7668L12.5086 9.81177L8.15251 8.15226L9.81201 12.5084Z",
|
||||
"fill": "currentColor"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M5.2124 10.3977L3.56266 12.0474L2.61995 11.1047L4.26969 9.455L5.2124 10.3977Z",
|
||||
"fill": "currentColor"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M3.66683 7.99992H1.3335V6.66659H3.66683V7.99992Z",
|
||||
"fill": "currentColor"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M5.2124 4.2688L4.26969 5.21151L2.61995 3.56177L3.56266 2.61906L5.2124 4.2688Z",
|
||||
"fill": "currentColor"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M12.0477 3.56177L10.3979 5.21151L9.45524 4.2688L11.105 2.61906L12.0477 3.56177Z",
|
||||
"fill": "currentColor"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M8.00016 3.66659H6.66683V1.33325H8.00016V3.66659Z",
|
||||
"fill": "currentColor"
|
||||
},
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "Trigger"
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
import * as React from 'react'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import data from './Trigger.json'
|
||||
|
||||
const Icon = ({
|
||||
ref,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement> & {
|
||||
ref?: React.RefObject<React.RefObject<HTMLOrSVGElement>>
|
||||
}) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'Trigger'
|
||||
|
||||
export default Icon
|
||||
@@ -1,3 +1,2 @@
|
||||
export { default as BoxSparkleFill } from './BoxSparkleFill'
|
||||
export { default as LeftCorner } from './LeftCorner'
|
||||
export { default as Trigger } from './Trigger'
|
||||
|
||||
@@ -28,23 +28,32 @@ describe('PluginTypeSwitch', () => {
|
||||
it('renders every supported plugin category', () => {
|
||||
renderSwitch()
|
||||
|
||||
expect(screen.getByText('category.all')).toBeInTheDocument()
|
||||
expect(screen.getByText('category.models')).toBeInTheDocument()
|
||||
expect(screen.getByText('category.tools')).toBeInTheDocument()
|
||||
expect(screen.getByText('category.datasources')).toBeInTheDocument()
|
||||
expect(screen.getByText('category.agents')).toBeInTheDocument()
|
||||
expect(screen.getByText('category.triggers')).toBeInTheDocument()
|
||||
expect(screen.getByText('category.extensions')).toBeInTheDocument()
|
||||
expect(screen.getByText('category.bundles')).toBeInTheDocument()
|
||||
expect(screen.getByRole('button', { name: 'category.all' })).toHaveAttribute(
|
||||
'aria-pressed',
|
||||
'true',
|
||||
)
|
||||
expect(screen.getByRole('button', { name: 'category.models' })).toHaveAttribute(
|
||||
'aria-pressed',
|
||||
'false',
|
||||
)
|
||||
expect(screen.getByRole('button', { name: 'category.tools' })).toBeInTheDocument()
|
||||
expect(screen.getByRole('button', { name: 'category.datasources' })).toBeInTheDocument()
|
||||
expect(screen.getByRole('button', { name: 'category.agents' })).toBeInTheDocument()
|
||||
expect(screen.getByRole('button', { name: 'category.triggers' })).toBeInTheDocument()
|
||||
expect(screen.getByRole('button', { name: 'category.extensions' })).toBeInTheDocument()
|
||||
expect(screen.getByRole('button', { name: 'category.bundles' })).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('updates the category in the URL when selected', async () => {
|
||||
const user = userEvent.setup()
|
||||
const { onUrlUpdate } = renderSwitch('?category=all')
|
||||
|
||||
await user.click(screen.getByText('category.models'))
|
||||
const modelsButton = screen.getByRole('button', { name: 'category.models' })
|
||||
modelsButton.focus()
|
||||
await user.keyboard('{Enter}')
|
||||
|
||||
await waitFor(() => expect(onUrlUpdate).toHaveBeenCalled())
|
||||
expect(onUrlUpdate.mock.calls.at(-1)?.[0].searchParams.get('category')).toBe('model')
|
||||
expect(modelsButton).toHaveAttribute('aria-pressed', 'true')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,18 +1,9 @@
|
||||
'use client'
|
||||
import type { ActivePluginType } from './constants'
|
||||
import { cn } from '@langgenius/dify-ui/cn'
|
||||
import {
|
||||
RiArchive2Line,
|
||||
RiBrain2Line,
|
||||
RiDatabase2Line,
|
||||
RiHammerLine,
|
||||
RiPuzzle2Line,
|
||||
RiSpeakAiLine,
|
||||
} from '@remixicon/react'
|
||||
import { useSetAtom } from 'jotai'
|
||||
import { Fragment } from 'react'
|
||||
import { useTranslation } from '#i18n'
|
||||
import { Trigger as TriggerIcon } from '@/app/components/base/icons/src/vender/plugin'
|
||||
import PluginIcon from '@/app/components/base/icons/src/vender/plugin/Plugin'
|
||||
import { searchModeAtom, useActivePluginType } from './atoms'
|
||||
import { PLUGIN_CATEGORY_WITH_COLLECTIONS, PLUGIN_TYPE_SEARCH_MAP } from './constants'
|
||||
@@ -43,37 +34,37 @@ const PluginTypeSwitch = ({ className, variant = 'default' }: PluginTypeSwitchPr
|
||||
{
|
||||
value: PLUGIN_TYPE_SEARCH_MAP.model,
|
||||
text: t(($) => $['category.models'], { ns: 'plugin' }),
|
||||
icon: <RiBrain2Line className={iconClassName} />,
|
||||
icon: <span aria-hidden className={cn('i-ri-brain-2-line', iconClassName)} />,
|
||||
},
|
||||
{
|
||||
value: PLUGIN_TYPE_SEARCH_MAP.tool,
|
||||
text: t(($) => $['category.tools'], { ns: 'plugin' }),
|
||||
icon: <RiHammerLine className={iconClassName} />,
|
||||
icon: <span aria-hidden className={cn('i-ri-hammer-line', iconClassName)} />,
|
||||
},
|
||||
{
|
||||
value: PLUGIN_TYPE_SEARCH_MAP.datasource,
|
||||
text: t(($) => $['category.datasources'], { ns: 'plugin' }),
|
||||
icon: <RiDatabase2Line className={iconClassName} />,
|
||||
icon: <span aria-hidden className={cn('i-ri-database-2-line', iconClassName)} />,
|
||||
},
|
||||
{
|
||||
value: PLUGIN_TYPE_SEARCH_MAP.agent,
|
||||
text: t(($) => $['category.agents'], { ns: 'plugin' }),
|
||||
icon: <RiSpeakAiLine className={iconClassName} />,
|
||||
icon: <span aria-hidden className={cn('i-ri-speak-ai-line', iconClassName)} />,
|
||||
},
|
||||
{
|
||||
value: PLUGIN_TYPE_SEARCH_MAP.trigger,
|
||||
text: t(($) => $['category.triggers'], { ns: 'plugin' }),
|
||||
icon: <TriggerIcon className={iconClassName} />,
|
||||
icon: <span aria-hidden className={cn('i-custom-vender-plugin-trigger', iconClassName)} />,
|
||||
},
|
||||
{
|
||||
value: PLUGIN_TYPE_SEARCH_MAP.extension,
|
||||
text: t(($) => $['category.extensions'], { ns: 'plugin' }),
|
||||
icon: <RiPuzzle2Line className={iconClassName} />,
|
||||
icon: <span aria-hidden className={cn('i-ri-puzzle-2-line', iconClassName)} />,
|
||||
},
|
||||
{
|
||||
value: PLUGIN_TYPE_SEARCH_MAP.bundle,
|
||||
text: t(($) => $['category.bundles'], { ns: 'plugin' }),
|
||||
icon: <RiArchive2Line className={iconClassName} />,
|
||||
icon: <span aria-hidden className={cn('i-ri-archive-2-line', iconClassName)} />,
|
||||
},
|
||||
]
|
||||
|
||||
@@ -91,9 +82,11 @@ const PluginTypeSwitch = ({ className, variant = 'default' }: PluginTypeSwitchPr
|
||||
|
||||
return (
|
||||
<Fragment key={option.value}>
|
||||
<div
|
||||
<button
|
||||
type="button"
|
||||
aria-pressed={isActive}
|
||||
className={cn(
|
||||
'flex h-8 cursor-pointer items-center rounded-lg border border-transparent px-2.5 system-md-medium whitespace-nowrap',
|
||||
'flex h-8 cursor-pointer appearance-none items-center rounded-lg border border-transparent px-2.5 system-md-medium whitespace-nowrap outline-hidden focus-visible:ring-2 focus-visible:ring-state-accent-solid',
|
||||
isHero ? 'text-text-primary-on-surface' : 'text-text-tertiary',
|
||||
!isActive &&
|
||||
(isHero
|
||||
@@ -113,7 +106,7 @@ const PluginTypeSwitch = ({ className, variant = 'default' }: PluginTypeSwitchPr
|
||||
>
|
||||
{option.icon}
|
||||
{option.text}
|
||||
</div>
|
||||
</button>
|
||||
{isHero && index === 0 && (
|
||||
<div
|
||||
aria-hidden
|
||||
|
||||
Reference in New Issue
Block a user