mirror of
https://github.com/langgenius/dify.git
synced 2026-03-25 00:07:56 +08:00
chore: add tracking info of in site message (#33394)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@ -1,7 +1,13 @@
|
||||
import type { ComponentProps } from 'react'
|
||||
import type { InSiteMessageActionItem } from './index'
|
||||
import { fireEvent, render, screen } from '@testing-library/react'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import InSiteMessage from './index'
|
||||
|
||||
vi.mock('@/app/components/base/amplitude', () => ({
|
||||
trackEvent: vi.fn(),
|
||||
}))
|
||||
|
||||
describe('InSiteMessage', () => {
|
||||
const originalLocation = window.location
|
||||
|
||||
@ -18,9 +24,10 @@ describe('InSiteMessage', () => {
|
||||
vi.unstubAllGlobals()
|
||||
})
|
||||
|
||||
const renderComponent = (actions: InSiteMessageActionItem[], props?: Partial<React.ComponentProps<typeof InSiteMessage>>) => {
|
||||
const renderComponent = (actions: InSiteMessageActionItem[], props?: Partial<ComponentProps<typeof InSiteMessage>>) => {
|
||||
return render(
|
||||
<InSiteMessage
|
||||
notificationId="test-notification-id"
|
||||
title="Title\\nLine"
|
||||
subtitle="Subtitle\\nLine"
|
||||
main="Main content"
|
||||
@ -34,8 +41,8 @@ describe('InSiteMessage', () => {
|
||||
describe('Rendering', () => {
|
||||
it('should render title, subtitle, markdown content, and action buttons', () => {
|
||||
const actions: InSiteMessageActionItem[] = [
|
||||
{ action: 'close', text: 'Close', type: 'default' },
|
||||
{ action: 'link', text: 'Learn more', type: 'primary', data: 'https://example.com' },
|
||||
{ action: 'close', action_name: 'dismiss', text: 'Close', type: 'default' },
|
||||
{ action: 'link', action_name: 'learn_more', text: 'Learn more', type: 'primary', data: 'https://example.com' },
|
||||
]
|
||||
|
||||
renderComponent(actions, { className: 'custom-message' })
|
||||
@ -56,7 +63,7 @@ describe('InSiteMessage', () => {
|
||||
})
|
||||
|
||||
it('should fallback to default header background when headerBgUrl is empty string', () => {
|
||||
const actions: InSiteMessageActionItem[] = [{ action: 'close', text: 'Close', type: 'default' }]
|
||||
const actions: InSiteMessageActionItem[] = [{ action: 'close', action_name: 'dismiss', text: 'Close', type: 'default' }]
|
||||
|
||||
const { container } = renderComponent(actions, { headerBgUrl: '' })
|
||||
const header = container.querySelector('div[style]')
|
||||
@ -68,7 +75,7 @@ describe('InSiteMessage', () => {
|
||||
describe('Actions', () => {
|
||||
it('should call onAction and hide component when close action is clicked', () => {
|
||||
const onAction = vi.fn()
|
||||
const closeAction: InSiteMessageActionItem = { action: 'close', text: 'Close', type: 'default' }
|
||||
const closeAction: InSiteMessageActionItem = { action: 'close', action_name: 'dismiss', text: 'Close', type: 'default' }
|
||||
|
||||
renderComponent([closeAction], { onAction })
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Close' }))
|
||||
@ -80,6 +87,7 @@ describe('InSiteMessage', () => {
|
||||
it('should open a new tab when link action data is a string', () => {
|
||||
const linkAction: InSiteMessageActionItem = {
|
||||
action: 'link',
|
||||
action_name: 'confirm',
|
||||
text: 'Open link',
|
||||
type: 'primary',
|
||||
data: 'https://example.com',
|
||||
@ -103,6 +111,7 @@ describe('InSiteMessage', () => {
|
||||
|
||||
const linkAction: InSiteMessageActionItem = {
|
||||
action: 'link',
|
||||
action_name: 'confirm',
|
||||
text: 'Open self',
|
||||
type: 'primary',
|
||||
data: { href: 'https://example.com/self', target: '_self' },
|
||||
@ -118,6 +127,7 @@ describe('InSiteMessage', () => {
|
||||
it('should not trigger navigation when link data is invalid', () => {
|
||||
const linkAction: InSiteMessageActionItem = {
|
||||
action: 'link',
|
||||
action_name: 'confirm',
|
||||
text: 'Broken link',
|
||||
type: 'primary',
|
||||
data: { rel: 'noopener' },
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { useMemo, useState } from 'react'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { trackEvent } from '@/app/components/base/amplitude'
|
||||
import Button from '@/app/components/base/button'
|
||||
import { MarkdownWithDirective } from '@/app/components/base/markdown-with-directive'
|
||||
import { cn } from '@/utils/classnames'
|
||||
@ -10,12 +11,14 @@ type InSiteMessageButtonType = 'primary' | 'default'
|
||||
|
||||
export type InSiteMessageActionItem = {
|
||||
action: InSiteMessageAction
|
||||
action_name: string // for tracing and analytics
|
||||
data?: unknown
|
||||
text: string
|
||||
type: InSiteMessageButtonType
|
||||
}
|
||||
|
||||
type InSiteMessageProps = {
|
||||
notificationId: string
|
||||
actions: InSiteMessageActionItem[]
|
||||
className?: string
|
||||
headerBgUrl?: string
|
||||
@ -52,6 +55,7 @@ function normalizeLinkData(data: unknown): { href: string, rel?: string, target?
|
||||
const DEFAULT_HEADER_BG_URL = '/in-site-message/header-bg.svg'
|
||||
|
||||
function InSiteMessage({
|
||||
notificationId,
|
||||
actions,
|
||||
className,
|
||||
headerBgUrl = DEFAULT_HEADER_BG_URL,
|
||||
@ -70,7 +74,17 @@ function InSiteMessage({
|
||||
}
|
||||
}, [headerBgUrl])
|
||||
|
||||
useEffect(() => {
|
||||
trackEvent('in_site_message_show', {
|
||||
notification_id: notificationId,
|
||||
})
|
||||
}, [notificationId])
|
||||
|
||||
const handleAction = (item: InSiteMessageActionItem) => {
|
||||
trackEvent('in_site_message_action', {
|
||||
notification_id: notificationId,
|
||||
action: item.action_name,
|
||||
})
|
||||
onAction?.(item)
|
||||
|
||||
if (item.action === 'close') {
|
||||
|
||||
@ -15,11 +15,16 @@ const {
|
||||
mockNotificationDismiss: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('@/config', () => ({
|
||||
get IS_CLOUD_EDITION() {
|
||||
return mockConfig.isCloudEdition
|
||||
},
|
||||
}))
|
||||
vi.mock(import('@/config'), async (importOriginal) => {
|
||||
const actual = await importOriginal()
|
||||
|
||||
return {
|
||||
...actual,
|
||||
get IS_CLOUD_EDITION() {
|
||||
return mockConfig.isCloudEdition
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
vi.mock('@/service/client', () => ({
|
||||
consoleQuery: {
|
||||
|
||||
@ -75,6 +75,7 @@ function InSiteMessageNotification() {
|
||||
const fallbackActions: InSiteMessageActionItem[] = [
|
||||
{
|
||||
type: 'default',
|
||||
action_name: 'dismiss',
|
||||
text: t('operation.close', { ns: 'common' }),
|
||||
action: 'close',
|
||||
},
|
||||
@ -96,6 +97,7 @@ function InSiteMessageNotification() {
|
||||
return (
|
||||
<InSiteMessage
|
||||
key={notification.notification_id}
|
||||
notificationId={notification.notification_id}
|
||||
title={notification.title}
|
||||
subtitle={notification.subtitle}
|
||||
headerBgUrl={notification.title_pic_url}
|
||||
|
||||
Reference in New Issue
Block a user