From d7905fb5fe56c5c7a293b058ed173b4df08af8f5 Mon Sep 17 00:00:00 2001 From: CodingOnStar Date: Fri, 17 Oct 2025 14:45:37 +0800 Subject: [PATCH 1/5] feat: enhance filter components with Google Analytics event tracking on clear actions --- web/app/components/app/log/filter.tsx | 8 +++++++- web/app/components/app/workflow-log/filter.tsx | 8 +++++++- web/app/components/base/ga/index.tsx | 2 ++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/web/app/components/app/log/filter.tsx b/web/app/components/app/log/filter.tsx index affaa879b0..865ac4acc0 100644 --- a/web/app/components/app/log/filter.tsx +++ b/web/app/components/app/log/filter.tsx @@ -54,7 +54,13 @@ const Filter: FC = ({ isChatMode, appId, queryParams, setQueryPara }) setQueryParams({ ...queryParams, period: item.value }) }} - onClear={() => setQueryParams({ ...queryParams, period: '9' })} + onClear={() => { + sendGAEvent('filter_chat_conversation_period', { + period: 'reset', + period_name: 'reset', + }) + setQueryParams({ ...queryParams, period: '9' }) + }} items={Object.entries(TIME_PERIOD_MAPPING).map(([k, v]) => ({ value: k, name: t(`appLog.filter.period.${v.name}`) }))} /> = ({ queryParams, setQueryParams }: IFilterProps) }) setQueryParams({ ...queryParams, status: item.value as string }) }} - onClear={() => setQueryParams({ ...queryParams, status: 'all' })} + onClear={() => { + sendGAEvent('filter_workflow_status_clear', { + status: 'reset', + status_name: 'reset', + }) + setQueryParams({ ...queryParams, status: 'all' }) + }} items={[{ value: 'all', name: 'All' }, { value: 'succeeded', name: 'Success' }, { value: 'failed', name: 'Fail' }, diff --git a/web/app/components/base/ga/index.tsx b/web/app/components/base/ga/index.tsx index a33b6546e4..8da97cb1c9 100644 --- a/web/app/components/base/ga/index.tsx +++ b/web/app/components/base/ga/index.tsx @@ -21,6 +21,8 @@ export type IGAProps = { const GA: FC = ({ gaType, }) => { + console.log('IS_CE_EDITION', IS_CE_EDITION) + console.log('process.env.NODE_ENV', process.env.NODE_ENV) if (IS_CE_EDITION) return null From a2b1a148d3a27c0141d187885690a85c017df1c1 Mon Sep 17 00:00:00 2001 From: CodingOnStar Date: Fri, 17 Oct 2025 17:07:03 +0800 Subject: [PATCH 2/5] refactor: remove console logs from Google Analytics component --- web/app/components/base/ga/index.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/web/app/components/base/ga/index.tsx b/web/app/components/base/ga/index.tsx index 8da97cb1c9..a33b6546e4 100644 --- a/web/app/components/base/ga/index.tsx +++ b/web/app/components/base/ga/index.tsx @@ -21,8 +21,6 @@ export type IGAProps = { const GA: FC = ({ gaType, }) => { - console.log('IS_CE_EDITION', IS_CE_EDITION) - console.log('process.env.NODE_ENV', process.env.NODE_ENV) if (IS_CE_EDITION) return null From 66bca831cc4b1b96f21a0b6a76e6c8847991a07b Mon Sep 17 00:00:00 2001 From: CodingOnStar Date: Fri, 17 Oct 2025 17:22:49 +0800 Subject: [PATCH 3/5] refactor: update Google Analytics component to use window.gtag for event tracking --- web/app/components/base/ga/index.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/web/app/components/base/ga/index.tsx b/web/app/components/base/ga/index.tsx index a33b6546e4..33f8ffb010 100644 --- a/web/app/components/base/ga/index.tsx +++ b/web/app/components/base/ga/index.tsx @@ -34,10 +34,10 @@ const GA: FC = ({ strategy="afterInteractive" dangerouslySetInnerHTML={{ __html: ` -window.dataLayer = window.dataLayer || []; -function gtag(){dataLayer.push(arguments);} -gtag('js', new Date()); -gtag('config', '${gaIdMaps[gaType]}'); + window.dataLayer = window.dataLayer || []; + window.gtag = function gtag(){window.dataLayer.push(arguments);}; + window.gtag('js', new Date()); + window.gtag('config', '${gaIdMaps[gaType]}'); `, }} nonce={nonce ?? undefined} @@ -56,7 +56,6 @@ gtag('config', '${gaIdMaps[gaType]}'); nonce={nonce ?? undefined} /> - ) } export default React.memo(GA) From c200bbb9fc7d44edbeaa3f3041cb4c2ad8448528 Mon Sep 17 00:00:00 2001 From: CodingOnStar Date: Fri, 17 Oct 2025 19:12:01 +0800 Subject: [PATCH 4/5] refactor: update Content Security Policy to include 'strict-dynamic' and improve nonce handling in Google Analytics component --- web/app/components/base/ga/index.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/web/app/components/base/ga/index.tsx b/web/app/components/base/ga/index.tsx index 33f8ffb010..759a91d18e 100644 --- a/web/app/components/base/ga/index.tsx +++ b/web/app/components/base/ga/index.tsx @@ -24,7 +24,8 @@ const GA: FC = ({ if (IS_CE_EDITION) return null - const nonce = process.env.NODE_ENV === 'production' ? (headers() as unknown as UnsafeUnwrappedHeaders).get('x-nonce') ?? '' : '' + const nonceValue = process.env.NODE_ENV === 'production' ? (headers() as unknown as UnsafeUnwrappedHeaders).get('x-nonce') : null + const nonce = nonceValue || undefined return ( <> @@ -40,20 +41,20 @@ const GA: FC = ({ window.gtag('config', '${gaIdMaps[gaType]}'); `, }} - nonce={nonce ?? undefined} + nonce={nonce} /> {/* Load GA script */}