From 8220f05b34a2e0d0ea61830cc29c7ca60f85620f Mon Sep 17 00:00:00 2001 From: CodingOnStar Date: Wed, 5 Aug 2026 18:09:05 +0800 Subject: [PATCH] feat: add marketplace template detail dialog --- .../marketplace/detail-dialog/frame.tsx | 96 +++++++++++++ .../marketplace/detail-dialog/index.tsx | 97 +++---------- .../__tests__/template-card.spec.tsx | 70 +++++++++- .../marketplace/templates/template-card.tsx | 128 +++++++++++------- .../templates/template-detail-dialog.tsx | 61 +++++++++ .../components/plugins/marketplace/utils.ts | 17 +++ 6 files changed, 333 insertions(+), 136 deletions(-) create mode 100644 web/app/components/plugins/marketplace/detail-dialog/frame.tsx create mode 100644 web/app/components/plugins/marketplace/templates/template-detail-dialog.tsx diff --git a/web/app/components/plugins/marketplace/detail-dialog/frame.tsx b/web/app/components/plugins/marketplace/detail-dialog/frame.tsx new file mode 100644 index 00000000000..ce503b8a5c5 --- /dev/null +++ b/web/app/components/plugins/marketplace/detail-dialog/frame.tsx @@ -0,0 +1,96 @@ +'use client' + +import { cn } from '@langgenius/dify-ui/cn' +import { Dialog, DialogCloseButton, DialogContent, DialogTitle } from '@langgenius/dify-ui/dialog' +import { useEffect, useRef, useState } from 'react' +import { useTranslation } from '#i18n' + +type MarketplaceDetailDialogFrameProps = { + open: boolean + src: string + title: string + onMessage?: (data: unknown) => void + onOpenChange: (open: boolean) => void +} + +export default function MarketplaceDetailDialogFrame({ + open, + src, + title, + onMessage, + onOpenChange, +}: MarketplaceDetailDialogFrameProps) { + const { t } = useTranslation() + const iframeRef = useRef(null) + const [isLoading, setIsLoading] = useState(true) + + useEffect(() => { + if (!open || !onMessage) return + + const marketplaceOrigin = new URL(src, window.location.href).origin + const handleMessage = (event: MessageEvent) => { + if (event.source !== iframeRef.current?.contentWindow || event.origin !== marketplaceOrigin) + return + + onMessage(event.data) + } + + window.addEventListener('message', handleMessage) + return () => window.removeEventListener('message', handleMessage) + }, [onMessage, open, src]) + + const handleOpenChange = (nextOpen: boolean) => { + if (!nextOpen) setIsLoading(true) + onOpenChange(nextOpen) + } + + return ( + + + {title} +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+