Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion oxlint-suppressions.json
Original file line number Diff line number Diff line change
Expand Up @@ -2967,7 +2967,7 @@
},
"web/app/components/workflow/nodes/agent/__tests__/integration.spec.tsx": {
"typescript/no-explicit-any": {
"count": 17
"count": 16
}
},
"web/app/components/workflow/nodes/agent/default.ts": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,7 @@ const LoadedFormContent = ({
return (
<div className={cn('mx-auto flex size-full max-w-180 flex-col items-center')}>
<div className="mt-4 flex w-full shrink-0 items-center gap-3 py-3">
<AppIcon
size="large"
iconType={site.icon_type}
icon={site.icon}
background={site.icon_background}
imageUrl={site.icon_url}
/>
<AppIcon size="large" icon={site} />
<div className="grow system-xl-semibold text-text-primary">{site.title}</div>
</div>
<div className="h-0 w-full grow overflow-y-auto">
Expand Down
10 changes: 1 addition & 9 deletions web/app/account/(commonLayout)/account-page/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use client'
import type { AppPartial } from '@dify/contracts/api/console/apps/types.gen'
import type { IItem } from '@/app/components/header/account-setting/collapse'
import { zIconType } from '@dify/contracts/api/console/apps/zod.gen'
import { Button } from '@langgenius/dify-ui/button'
import { useQuery, useSuspenseQuery } from '@tanstack/react-query'
import { useState } from 'react'
Expand Down Expand Up @@ -61,17 +60,10 @@ export default function AccountPage() {
if (!userProfile) return null

const renderAppItem = (item: AccountAppItem) => {
const appIconType = zIconType.safeParse(item.icon_type).data ?? null
return (
<div className="flex px-3 py-1">
<div className="mr-3">
<AppIcon
size="tiny"
iconType={appIconType}
icon={item.icon ?? undefined}
background={item.icon_background}
imageUrl={item.icon_url}
/>
<AppIcon size="tiny" icon={item} />
</div>
<div className="mt-0.75 system-sm-medium text-text-secondary">{item.name}</div>
</div>
Expand Down
5 changes: 1 addition & 4 deletions web/app/components/app-sidebar/app-detail-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,8 @@ function AppDetailContent({ appId, expand }: { appId: string; expand: boolean })
expand={expand}
appName={appTitle}
modeLabel={appDetail ? getAppModeLabel(appDetail.mode, t) : undefined}
iconType={appDetail?.icon_type}
icon={appDetail?.icon ?? undefined}
background={appDetail?.icon_background}
imageUrl={appDetail?.icon_url}
operationGroups={[]}
icon={appDetail}
/>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,6 @@ vi.mock('@/context/permission-state', async () => {
return createPermissionStateModuleMock(() => mockConsoleState.current)
})

vi.mock('../../../base/app-icon', () => ({
default: ({
size,
icon,
background,
}: {
size: string
icon: string
background: string
iconType?: string
imageUrl?: string
}) => (
<span data-size={size} data-icon={icon} data-bg={background}>
{icon}
</span>
),
}))

const defaultAppPermissionKeys = [
AppACLPermission.Edit,
AppACLPermission.ImportExportDSL,
Expand Down Expand Up @@ -96,7 +78,7 @@ describe('AppInfoTrigger', () => {
})
render(<AppInfoTrigger {...props} />)

expect(screen.getByText('🤖')).toHaveAttribute('data-size', 'medium')
expect(screen.getByText('🤖')).toBeInTheDocument()
expect(screen.getByText('My Chatbot')).toBeInTheDocument()
expect(screen.getByText('app.types.advanced')).toBeInTheDocument()
expect(screen.getByText('My Chatbot').closest('button')).toBeNull()
Expand All @@ -107,10 +89,10 @@ describe('AppInfoTrigger', () => {
expect(props.exportCheck).not.toHaveBeenCalled()
})

it('renders only the medium app icon when collapsed', () => {
it('renders only the app icon when collapsed', () => {
render(<AppInfoTrigger {...createProps({ expand: false })} />)

expect(screen.getByText('🤖')).toHaveAttribute('data-size', 'medium')
expect(screen.getByText('🤖')).toBeInTheDocument()
expect(screen.queryByText('Test App')).not.toBeInTheDocument()
expect(screen.queryByRole('button')).not.toBeInTheDocument()
})
Expand Down
21 changes: 4 additions & 17 deletions web/app/components/app-sidebar/app-info/app-info-header.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import type { ComponentProps } from 'react'
import type { AppIconProps } from '../../base/app-icon'
import type { Operation } from './app-operations'
import { cn } from '@langgenius/dify-ui/cn'
import AppIcon from '../../base/app-icon'
import AppOperations from './app-operations'

type AppInfoHeaderProps = Pick<
ComponentProps<typeof AppIcon>,
'iconType' | 'icon' | 'background' | 'imageUrl'
> & {
type AppInfoHeaderProps = {
icon: AppIconProps['icon']
expand: boolean
appName: string
modeLabel?: string
Expand All @@ -18,10 +16,7 @@ export default function AppInfoHeader({
expand,
appName,
modeLabel,
iconType,
icon,
background,
imageUrl,
operationGroups,
}: AppInfoHeaderProps) {
return (
Expand All @@ -32,15 +27,7 @@ export default function AppInfoHeader({
)}
>
<div className="flex shrink-0 items-center">
<AppIcon
size="medium"
rounded
decorative
iconType={iconType}
icon={icon}
background={background}
imageUrl={imageUrl}
/>
<AppIcon size="medium" shape="circle" icon={icon} />
</div>
{expand && (
<div className="flex min-w-0 flex-1 flex-col items-start justify-center gap-0.5 self-stretch">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,8 @@ const AppInfoTrigger = ({
expand={expand}
appName={appDetail.name}
modeLabel={modeLabel}
iconType={appDetail.icon_type}
icon={appDetail.icon ?? undefined}
background={appDetail.icon_background}
imageUrl={appDetail.icon_url}
operationGroups={[mainOperations, destructiveOperations, workflowConversionOperations]}
icon={appDetail}
/>
)
}
Expand Down
8 changes: 1 addition & 7 deletions web/app/components/app-sidebar/dataset-info/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,7 @@ const DatasetInfo = ({ expand }: DatasetInfoProps) => {
)}
>
<div className="flex shrink-0 items-center">
<AppIcon
size="medium"
iconType={iconInfo.icon_type}
icon={iconInfo.icon}
background={iconInfo.icon_background}
imageUrl={iconInfo.icon_url}
/>
<AppIcon size="medium" icon={iconInfo} />
</div>
{!expand && <span className="sr-only">{dataset.name}</span>}
{expand && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,15 +173,7 @@ export function WebAppAccessPointCard({
description={t(($) => $['studio.accessPoint.webAppDescription'], {
ns: 'deployments',
})}
icon={
<AppIcon
size="large"
iconType={appInfo.icon_type}
icon={appInfo.icon ?? undefined}
background={appInfo.icon_background}
imageUrl={appInfo.icon_url}
/>
}
icon={<AppIcon size="large" icon={appInfo} />}
status={status}
statusLabel={statusLabel}
highlighted={highlighted}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,19 +166,7 @@ export function EnvironmentWebAppCard({
description={t(($) => $['studio.accessPoint.webAppDescription'], {
ns: 'deployments',
})}
icon={
appInfo ? (
<AppIcon
size="large"
iconType={appInfo.icon_type}
icon={appInfo.icon ?? undefined}
background={appInfo.icon_background}
imageUrl={appInfo.icon_url}
/>
) : (
'i-ri-robot-2-line'
)
}
icon={appInfo ? <AppIcon size="large" icon={appInfo} /> : 'i-ri-robot-2-line'}
status={status}
statusLabel={statusLabel}
highlighted={highlighted}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,11 @@ const AgentTools: FC = () => {
<AppIcon
className="rounded-md"
size="xs"
icon={item.icon?.content}
background={item.icon?.background}
icon={{
icon_type: 'emoji',
icon: item.icon?.content,
icon_background: item.icon?.background,
}}
/>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,11 +214,7 @@ describe('dataset-config/card-item', () => {

renderItem(dataset)

const nameElement = screen.getByText(dataset.name)
const iconElement = nameElement.parentElement?.firstElementChild as HTMLElement

expect(iconElement)!.toHaveStyle({ background: '#FFF4ED' })
expect(iconElement).toHaveTextContent('📙')
expect(screen.getByText('📙')).toBeInTheDocument()
})

it('should apply mask overlay on mobile when drawer is open', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,7 @@ const Item: FC<ItemProps> = ({ config, onSave, onRemove, readonly = false, edita
)}
>
<div className="flex w-0 grow items-center space-x-1.5">
<AppIcon
size="tiny"
iconType={iconInfo.icon_type}
icon={iconInfo.icon}
background={iconInfo.icon_type === 'image' ? undefined : iconInfo.icon_background}
imageUrl={iconInfo.icon_type === 'image' ? iconInfo.icon_url : undefined}
/>
<AppIcon size="tiny" icon={iconInfo} />
<div className="w-0 grow truncate system-sm-medium text-text-secondary" title={config.name}>
{config.name}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,19 +154,7 @@ const SelectDataSet: FC<ISelectDataSetProps> = ({
>
<div className="mr-1 flex grow items-center overflow-hidden">
<div className={cn('mr-2', !item.embedding_available && 'opacity-30')}>
<AppIcon
size="tiny"
iconType={item.icon_info.icon_type}
icon={item.icon_info.icon}
background={
item.icon_info.icon_type === 'image'
? undefined
: item.icon_info.icon_background
}
imageUrl={
item.icon_info.icon_type === 'image' ? item.icon_info.icon_url : undefined
}
/>
<AppIcon size="tiny" icon={item.icon_info} />
</div>
<div
className={cn(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ describe('AppCard', () => {
vi.clearAllMocks()
})

afterEach(() => vi.restoreAllMocks())

it('exposes template creation only when creation is allowed', () => {
const { rerender } = render(
<AppCard app={app} canCreate onCreate={vi.fn()} onPreview={vi.fn()} />,
Expand All @@ -61,7 +63,9 @@ describe('AppCard', () => {
})

it('uses the remote image URL for image icons', () => {
render(
vi.spyOn(HTMLImageElement.prototype, 'complete', 'get').mockReturnValue(true)
vi.spyOn(HTMLImageElement.prototype, 'naturalWidth', 'get').mockReturnValue(32)
const { container } = render(
<AppCard
app={{
...app,
Expand All @@ -77,10 +81,8 @@ describe('AppCard', () => {
onPreview={vi.fn()}
/>,
)
expect(screen.getByRole('img', { name: 'app icon' })).toHaveAttribute(
'src',
'https://example.com/remote.png',
)
expect(container.querySelector('img')).toHaveAttribute('src', 'https://example.com/remote.png')
expect(screen.queryByRole('img')).not.toBeInTheDocument()
})

it('tracks and opens template preview in Cloud edition', async () => {
Expand Down
15 changes: 2 additions & 13 deletions web/app/components/app/create-app-dialog/app-card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,7 @@ const AppCard = ({ app, canCreate, onCreate, onPreview }: AppCardProps) => {
const { app: appBasicInfo } = app
const appName = appBasicInfo?.name ?? ''
const appMode = appBasicInfo?.mode ?? ''
const appIconType =
appBasicInfo?.icon_type === 'image' ||
appBasicInfo?.icon_type === 'emoji' ||
appBasicInfo?.icon_type === 'link'
? appBasicInfo.icon_type
: null

const canViewApp = deploymentEdition === 'CLOUD'
const handleShowTryAppPanel = useCallback(() => {
trackEvent('preview_template', {
Expand All @@ -54,13 +49,7 @@ const AppCard = ({ app, canCreate, onCreate, onPreview }: AppCardProps) => {
>
<div className="flex shrink-0 grow-0 items-center gap-3 pb-2">
<div className="relative shrink-0">
<AppIcon
size="large"
iconType={appIconType}
icon={appBasicInfo?.icon ?? ''}
background={appBasicInfo?.icon_background ?? ''}
imageUrl={appBasicInfo?.icon_url ?? ''}
/>
<AppIcon size="large" icon={appBasicInfo} />
<AppTypeIcon
wrapperClassName="absolute -bottom-0.5 -right-0.5 w-4 h-4 rounded-sm border border-divider-regular outline-solid outline-components-panel-on-panel-item-bg"
className="size-3"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,20 @@ import type {
WorkflowPath,
WorkflowReference,
} from '@dify/contracts/enterprise-app-deploy/types.gen'
import type { AppIconType } from '@/types/app'
import { Popover, PopoverContent, PopoverTitle, PopoverTrigger } from '@langgenius/dify-ui/popover'
import { Fragment } from 'react'
import { useTranslation } from 'react-i18next'
import AppIcon from '@/app/components/base/app-icon'
import Link from '@/next/link'
import { uniqueWorkflowPaths, workflowPathKey } from './utils/workflow-path'

function workflowReferenceIconType(reference: WorkflowReference): AppIconType | undefined {
if (reference.icon_type === 'emoji') return 'emoji'
if (reference.icon_type === 'image' || reference.icon_type === 'link') return 'image'

return undefined
}

function workflowReferenceImageUrl(reference: WorkflowReference) {
if (reference.icon_type !== 'image' && reference.icon_type !== 'link') return undefined

return reference.icon_url ?? reference.icon
}

export function WorkflowReferenceIcon({ reference }: { reference: WorkflowReference }) {
return (
<span aria-hidden className="shrink-0">
<AppIcon
size="xs"
iconType={workflowReferenceIconType(reference)}
icon={reference.icon}
background={reference.icon_background}
imageUrl={workflowReferenceImageUrl(reference)}
className="size-5 rounded-md text-sm"
icon={{ ...reference, icon_url: reference.icon_url ?? reference.icon }}
/>
</span>
)
Expand Down
Loading
Loading