Browse Source

fix: better qr code panel and webapp url regen confirmation (#6321)

Charles Zhou 9 months ago
parent
commit
0099ef6896

+ 1 - 1
web/app/components/app/overview/appCard.tsx

@@ -183,7 +183,7 @@ function AppCard({
                 <Confirm
                   type='warning'
                   title={t('appOverview.overview.appInfo.regenerate')}
-                  content={''}
+                  content={t('appOverview.overview.appInfo.regenerateNotice')}
                   isShow={showConfirmDelete}
                   onClose={() => setShowConfirmDelete(false)}
                   onConfirm={() => {

+ 39 - 19
web/app/components/base/qrcode/index.tsx

@@ -1,7 +1,6 @@
 'use client'
-import React, { useState } from 'react'
+import React, { useEffect, useRef, useState } from 'react'
 import { useTranslation } from 'react-i18next'
-import { debounce } from 'lodash-es'
 import QRCode from 'qrcode.react'
 import Tooltip from '../tooltip'
 import QrcodeStyle from './style.module.css'
@@ -16,10 +15,27 @@ const prefixEmbedded = 'appOverview.overview.appInfo.qrcode.title'
 
 const ShareQRCode = ({ content, selectorId, className }: Props) => {
   const { t } = useTranslation()
-  const [isShow, setisShow] = useState<boolean>(false)
-  const onClickShow = debounce(() => {
-    setisShow(true)
-  }, 100)
+  const [isShow, setIsShow] = useState<boolean>(false)
+  const qrCodeRef = useRef<HTMLDivElement>(null)
+
+  const toggleQRCode = (event: React.MouseEvent) => {
+    event.stopPropagation()
+    setIsShow(prev => !prev)
+  }
+
+  useEffect(() => {
+    const handleClickOutside = (event: MouseEvent) => {
+      if (qrCodeRef.current && !qrCodeRef.current.contains(event.target as Node))
+        setIsShow(false)
+    }
+
+    if (isShow)
+      document.addEventListener('click', handleClickOutside)
+
+    return () => {
+      document.removeEventListener('click', handleClickOutside)
+    }
+  }, [isShow])
 
   const downloadQR = () => {
     const canvas = document.getElementsByTagName('canvas')[0]
@@ -29,9 +45,9 @@ const ShareQRCode = ({ content, selectorId, className }: Props) => {
     link.click()
   }
 
-  const onMouseLeave = debounce(() => {
-    setisShow(false)
-  }, 500)
+  const handlePanelClick = (event: React.MouseEvent) => {
+    event.stopPropagation()
+  }
 
   return (
     <Tooltip
@@ -40,19 +56,23 @@ const ShareQRCode = ({ content, selectorId, className }: Props) => {
     >
       <div
         className={`w-8 h-8 cursor-pointer rounded-lg ${className ?? ''}`}
-        onMouseLeave={onMouseLeave}
-        onClick={onClickShow}
+        onClick={toggleQRCode}
       >
         <div className={`w-full h-full ${QrcodeStyle.QrcodeIcon} ${isShow ? QrcodeStyle.show : ''}`} />
-        {isShow && <div className={QrcodeStyle.qrcodeform}>
-          <QRCode size={160} value={content} className={QrcodeStyle.qrcodeimage}/>
-          <div className={QrcodeStyle.text}>
-            <div className={`text-gray-500 ${QrcodeStyle.scan}`}>{t('appOverview.overview.appInfo.qrcode.scan')}</div>
-            <div className={`text-gray-500 ${QrcodeStyle.scan}`}>·</div>
-            <div className={QrcodeStyle.download} onClick={downloadQR}>{t('appOverview.overview.appInfo.qrcode.download')}</div>
+        {isShow && (
+          <div
+            ref={qrCodeRef}
+            className={QrcodeStyle.qrcodeform}
+            onClick={handlePanelClick}
+          >
+            <QRCode size={160} value={content} className={QrcodeStyle.qrcodeimage}/>
+            <div className={QrcodeStyle.text}>
+              <div className={`text-gray-500 ${QrcodeStyle.scan}`}>{t('appOverview.overview.appInfo.qrcode.scan')}</div>
+              <div className={`text-gray-500 ${QrcodeStyle.scan}`}>·</div>
+              <div className={QrcodeStyle.download} onClick={downloadQR}>{t('appOverview.overview.appInfo.qrcode.download')}</div>
+            </div>
           </div>
-        </div>
-        }
+        )}
       </div>
     </Tooltip>
   )

+ 4 - 4
web/app/components/base/qrcode/style.module.css

@@ -37,6 +37,7 @@
   flex-direction: row;
   align-items: center;
   justify-content: center;
+  white-space: nowrap;
   gap: 4px;
 }
 .qrcodeform {
@@ -46,7 +47,8 @@
   margin: 0 !important;
   margin-top: 4px !important;
   margin-left: -75px !important;
-  position: absolute;
+  width: fit-content;
+  position: relative;
   border-radius: 8px;
   background-color: #fff;
   box-shadow: 0 12px 16px -4px rgba(16, 24, 40, 0.08),
@@ -54,8 +56,6 @@
   overflow: hidden;
   align-items: center;
   justify-content: center;
-  padding: 12px;
+  padding: 15px;
   gap: 8px;
-  z-index: 3;
-  font-family: "PingFang SC", serif;
 }

+ 9 - 9
web/i18n/en-US/app-overview.ts

@@ -3,23 +3,23 @@ const translation = {
     firstStepTip: 'To get started,',
     enterKeyTip: 'enter your OpenAI API Key below',
     getKeyTip: 'Get your API Key from OpenAI dashboard',
-    placeholder: 'Your OpenAI API Key(eg.sk-xxxx)',
+    placeholder: 'Your OpenAI API Key (eg.sk-xxxx)',
   },
   apiKeyInfo: {
     cloud: {
       trial: {
         title: 'You are using the {{providerName}} trial quota.',
-        description: 'The trial quota is provided for your testing use. Before the trial quota calls are exhausted, please set up your own model provider or purchase additional quota.',
+        description: 'The trial quota is provided for your testing purposes. Before the trial quota is exhausted, please set up your own model provider or purchase additional quota.',
       },
       exhausted: {
         title: 'Your trial quota have been used up, please set up your APIKey.',
-        description: 'Your trial quota has been exhausted. Please set up your own model provider or purchase additional quota.',
+        description: 'You have exhausted your trial quota. Please set up your own model provider or purchase additional quota.',
       },
     },
     selfHost: {
       title: {
         row1: 'To get started,',
-        row2: 'setup your  model provider first.',
+        row2: 'setup your model provider first.',
       },
     },
     callTimes: 'Call times',
@@ -76,8 +76,8 @@ const translation = {
         copy: 'Copy',
       },
       qrcode: {
-        title: 'QR code to share',
-        scan: 'Scan Share Application',
+        title: 'Link QR Code',
+        scan: 'Scan To Share',
         download: 'Download QR Code',
       },
       customize: {
@@ -103,14 +103,14 @@ const translation = {
       },
     },
     apiInfo: {
-      title: 'Backend service API',
+      title: 'Backend Service API',
       explanation: 'Easily integrated into your application',
       accessibleAddress: 'Service API Endpoint',
       doc: 'API Reference',
     },
     status: {
-      running: 'In service',
-      disable: 'Disable',
+      running: 'In Service',
+      disable: 'Disabled',
     },
   },
   analysis: {