From a430284aa21e3ae1f0d5654e55b2ad2852519cc2 Mon Sep 17 00:00:00 2001
From: wwf <yearningwang@iqtogether.com>
Date: 星期三, 04 六月 2025 15:17:49 +0800
Subject: [PATCH] 初始化

---
 app/components/app/app-publisher/index.tsx |  320 +++++++++++++++++++++++------------------------------
 1 files changed, 140 insertions(+), 180 deletions(-)

diff --git a/app/components/app/app-publisher/index.tsx b/app/components/app/app-publisher/index.tsx
index 1214483..3ba35a7 100644
--- a/app/components/app/app-publisher/index.tsx
+++ b/app/components/app/app-publisher/index.tsx
@@ -5,17 +5,9 @@
 } from 'react'
 import { useTranslation } from 'react-i18next'
 import dayjs from 'dayjs'
-import {
-  RiArrowDownSLine,
-  RiPlanetLine,
-  RiPlayCircleLine,
-  RiPlayList2Line,
-  RiTerminalBoxLine,
-} from '@remixicon/react'
-import { useKeyPress } from 'ahooks'
+import { RiArrowDownSLine, RiPlanetLine } from '@remixicon/react'
 import Toast from '../../base/toast'
 import type { ModelAndParameter } from '../configuration/debug/types'
-import { getKeyboardKeyCodeBySystem } from '../../workflow/utils'
 import SuggestedAction from './suggested-action'
 import PublishWithMultipleModel from './publish-with-multiple-model'
 import Button from '@/app/components/base/button'
@@ -24,16 +16,17 @@
   PortalToFollowElemContent,
   PortalToFollowElemTrigger,
 } from '@/app/components/base/portal-to-follow-elem'
-import { WEB_PREFIX } from '@/config'
 import { fetchInstalledAppList } from '@/service/explore'
 import EmbeddedModal from '@/app/components/app/overview/embedded'
 import { useStore as useAppStore } from '@/app/components/app/store'
 import { useGetLanguage } from '@/context/i18n'
+import { PlayCircle } from '@/app/components/base/icons/src/vender/line/mediaAndDevices'
 import { CodeBrowser } from '@/app/components/base/icons/src/vender/line/development'
+import { LeftIndent02 } from '@/app/components/base/icons/src/vender/line/editor'
+import { FileText } from '@/app/components/base/icons/src/vender/line/files'
 import WorkflowToolConfigureButton from '@/app/components/tools/workflow-tool/configure-button'
 import type { InputVar } from '@/app/components/workflow/types'
 import { appDefaultIconBackground } from '@/config'
-import type { PublishWorkflowParams } from '@/types/workflow'
 
 export type AppPublisherProps = {
   disabled?: boolean
@@ -44,7 +37,7 @@
   debugWithMultipleModel?: boolean
   multipleModelConfigs?: ModelAndParameter[]
   /** modelAndParameter is passed when debugWithMultipleModel is true */
-  onPublish?: (params?: any) => Promise<any> | any
+  onPublish?: (modelAndParameter?: ModelAndParameter) => Promise<any> | any
   onRestore?: () => Promise<any> | any
   onToggle?: (state: boolean) => void
   crossAxisOffset?: number
@@ -52,8 +45,6 @@
   inputs?: InputVar[]
   onRefreshData?: () => void
 }
-
-const PUBLISH_SHORTCUT = ['鈱�', '鈬�', 'P']
 
 const AppPublisher = ({
   disabled = false,
@@ -77,29 +68,28 @@
   const { app_base_url: appBaseURL = '', access_token: accessToken = '' } = appDetail?.site ?? {}
   const appMode = (appDetail?.mode !== 'completion' && appDetail?.mode !== 'workflow') ? 'chat' : appDetail.mode
   const appURL = `${appBaseURL}/${appMode}/${accessToken}`
-  const isChatApp = ['chat', 'agent-chat', 'completion'].includes(appDetail?.mode || '')
 
   const language = useGetLanguage()
   const formatTimeFromNow = useCallback((time: number) => {
     return dayjs(time).locale(language === 'zh_Hans' ? 'zh-cn' : language.replace('_', '-')).fromNow()
   }, [language])
 
-  const handlePublish = useCallback(async (params?: ModelAndParameter | PublishWorkflowParams) => {
+  const handlePublish = async (modelAndParameter?: ModelAndParameter) => {
     try {
-      await onPublish?.(params)
+      await onPublish?.(modelAndParameter)
       setPublished(true)
     }
-    catch {
+    catch (e) {
       setPublished(false)
     }
-  }, [onPublish])
+  }
 
   const handleRestore = useCallback(async () => {
     try {
       await onRestore?.()
       setOpen(false)
     }
-    catch {}
+    catch (e) { }
   }, [onRestore])
 
   const handleTrigger = useCallback(() => {
@@ -121,7 +111,7 @@
     try {
       const { installed_apps }: any = await fetchInstalledAppList(appDetail?.id) || {}
       if (installed_apps?.length > 0)
-        window.open(`${WEB_PREFIX}/explore/installed/${installed_apps[0].id}`, '_blank')
+        window.open(`/explore/installed/${installed_apps[0].id}`, '_blank')
       else
         throw new Error('No app found in Explore')
     }
@@ -132,172 +122,142 @@
 
   const [embeddingModalOpen, setEmbeddingModalOpen] = useState(false)
 
-  useKeyPress(`${getKeyboardKeyCodeBySystem('ctrl')}.shift.p`, (e) => {
-    e.preventDefault()
-    if (publishDisabled || published)
-      return
-    handlePublish()
-  },
-  { exactMatch: true, useCapture: true })
-
   return (
-    <>
-      <PortalToFollowElem
-        open={open}
-        onOpenChange={setOpen}
-        placement='bottom-end'
-        offset={{
-          mainAxis: 4,
-          crossAxis: crossAxisOffset,
-        }}
-      >
-        <PortalToFollowElemTrigger onClick={handleTrigger}>
-          <Button
-            variant='primary'
-            className='p-2'
-            disabled={disabled}
-          >
-            {t('workflow.common.publish')}
-            <RiArrowDownSLine className='h-4 w-4 text-components-button-primary-text' />
-          </Button>
-        </PortalToFollowElemTrigger>
-        <PortalToFollowElemContent className='z-[11]'>
-          <div className='w-[320px] rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xl shadow-shadow-shadow-5'>
-            <div className='p-4 pt-3'>
-              <div className='system-xs-medium-uppercase flex h-6 items-center text-text-tertiary'>
-                {publishedAt ? t('workflow.common.latestPublished') : t('workflow.common.currentDraftUnpublished')}
-              </div>
-              {publishedAt
-                ? (
-                  <div className='flex items-center justify-between'>
-                    <div className='system-sm-medium flex items-center text-text-secondary'>
-                      {t('workflow.common.publishedAt')} {formatTimeFromNow(publishedAt)}
-                    </div>
-                    {isChatApp && <Button
-                      variant='secondary-accent'
-                      size='small'
-                      onClick={handleRestore}
-                      disabled={published}
-                    >
-                      {t('workflow.common.restore')}
-                    </Button>}
+    <PortalToFollowElem
+      open={open}
+      onOpenChange={setOpen}
+      placement='bottom-end'
+      offset={{
+        mainAxis: 4,
+        crossAxis: crossAxisOffset,
+      }}
+    >
+      <PortalToFollowElemTrigger onClick={handleTrigger}>
+        <Button
+          variant='primary'
+          className='pl-3 pr-2'
+          disabled={disabled}
+        >
+          {t('workflow.common.publish')}
+          <RiArrowDownSLine className='w-4 h-4 ml-0.5' />
+        </Button>
+      </PortalToFollowElemTrigger>
+      <PortalToFollowElemContent className='z-[11]'>
+        <div className='w-[336px] bg-white rounded-2xl border-[0.5px] border-gray-200 shadow-xl'>
+          <div className='p-4 pt-3'>
+            <div className='flex items-center h-6 text-xs font-medium text-gray-500 uppercase'>
+              {publishedAt ? t('workflow.common.latestPublished') : t('workflow.common.currentDraftUnpublished')}
+            </div>
+            {publishedAt
+              ? (
+                <div className='flex justify-between items-center h-[18px]'>
+                  <div className='flex items-center mt-[3px] mb-[3px] leading-[18px] text-[13px] font-medium text-gray-700'>
+                    {t('workflow.common.publishedAt')} {formatTimeFromNow(publishedAt)}
                   </div>
-                )
-                : (
-                  <div className='system-sm-medium flex items-center text-text-secondary'>
-                    {t('workflow.common.autoSaved')} 路 {Boolean(draftUpdatedAt) && formatTimeFromNow(draftUpdatedAt!)}
-                  </div>
-                )}
-              {debugWithMultipleModel
-                ? (
-                  <PublishWithMultipleModel
-                    multipleModelConfigs={multipleModelConfigs}
-                    onSelect={item => handlePublish(item)}
-                  // textGenerationModelList={textGenerationModelList}
-                  />
-                )
-                : (
                   <Button
-                    variant='primary'
-                    className='mt-3 w-full'
-                    onClick={() => handlePublish()}
-                    disabled={publishDisabled || published}
+                    className={`
+                      ml-2 px-2 text-primary-600
+                      ${published && 'text-primary-300 border-gray-100'}
+                    `}
+                    size='small'
+                    onClick={handleRestore}
+                    disabled={published}
                   >
-                    {
-                      published
-                        ? t('workflow.common.published')
-                        : (
-                          <div className='flex gap-1'>
-                            <span>{t('workflow.common.publishUpdate')}</span>
-                            <div className='flex gap-0.5'>
-                              {PUBLISH_SHORTCUT.map(key => (
-                                <span key={key} className='system-kbd h-4 w-4 rounded-[4px] bg-components-kbd-bg-white text-text-primary-on-surface'>
-                                  {key}
-                                </span>
-                              ))}
-                            </div>
-                          </div>
-                        )
-                    }
+                    {t('workflow.common.restore')}
                   </Button>
-                )
-              }
-            </div>
-            <div className='border-t-[0.5px] border-t-divider-regular p-4 pt-3'>
-              <SuggestedAction
-                disabled={!publishedAt}
-                link={appURL}
-                icon={<RiPlayCircleLine className='h-4 w-4' />}
-              >
-                {t('workflow.common.runApp')}
-              </SuggestedAction>
-              {appDetail?.mode === 'workflow' || appDetail?.mode === 'completion'
-                ? (
-                  <SuggestedAction
-                    disabled={!publishedAt}
-                    link={`${appURL}${appURL.includes('?') ? '&' : '?'}mode=batch`}
-                    icon={<RiPlayList2Line className='h-4 w-4' />}
-                  >
-                    {t('workflow.common.batchRunApp')}
-                  </SuggestedAction>
-                )
-                : (
-                  <SuggestedAction
-                    onClick={() => {
-                      setEmbeddingModalOpen(true)
-                      handleTrigger()
-                    }}
-                    disabled={!publishedAt}
-                    icon={<CodeBrowser className='h-4 w-4' />}
-                  >
-                    {t('workflow.common.embedIntoSite')}
-                  </SuggestedAction>
-                )}
-              <SuggestedAction
-                onClick={() => {
-                  publishedAt && handleOpenInExplore()
-                }}
-                disabled={!publishedAt}
-                icon={<RiPlanetLine className='h-4 w-4' />}
-              >
-                {t('workflow.common.openInExplore')}
-              </SuggestedAction>
-              <SuggestedAction
-                disabled={!publishedAt}
-                link='./develop'
-                icon={<RiTerminalBoxLine className='h-4 w-4' />}
-              >
-                {t('workflow.common.accessAPIReference')}
-              </SuggestedAction>
-              {appDetail?.mode === 'workflow' && (
-                <WorkflowToolConfigureButton
-                  disabled={!publishedAt}
-                  published={!!toolPublished}
-                  detailNeedUpdate={!!toolPublished && published}
-                  workflowAppId={appDetail?.id}
-                  icon={{
-                    content: (appDetail.icon_type === 'image' ? '馃' : appDetail?.icon) || '馃',
-                    background: (appDetail.icon_type === 'image' ? appDefaultIconBackground : appDetail?.icon_background) || appDefaultIconBackground,
-                  }}
-                  name={appDetail?.name}
-                  description={appDetail?.description}
-                  inputs={inputs}
-                  handlePublish={handlePublish}
-                  onRefreshData={onRefreshData}
-                />
+                </div>
+              )
+              : (
+                <div className='flex items-center h-[18px] leading-[18px] text-[13px] font-medium text-gray-700'>
+                  {t('workflow.common.autoSaved')} 路 {Boolean(draftUpdatedAt) && formatTimeFromNow(draftUpdatedAt!)}
+                </div>
               )}
-            </div>
+            {debugWithMultipleModel
+              ? (
+                <PublishWithMultipleModel
+                  multipleModelConfigs={multipleModelConfigs}
+                  onSelect={item => handlePublish(item)}
+                // textGenerationModelList={textGenerationModelList}
+                />
+              )
+              : (
+                <Button
+                  variant='primary'
+                  className='w-full mt-3'
+                  onClick={() => handlePublish()}
+                  disabled={publishDisabled || published}
+                >
+                  {
+                    published
+                      ? t('workflow.common.published')
+                      : publishedAt ? t('workflow.common.update') : t('workflow.common.publish')
+                  }
+                </Button>
+              )
+            }
           </div>
-        </PortalToFollowElemContent>
-        <EmbeddedModal
-          siteInfo={appDetail?.site}
-          isShow={embeddingModalOpen}
-          onClose={() => setEmbeddingModalOpen(false)}
-          appBaseUrl={appBaseURL}
-          accessToken={accessToken}
-        />
-      </PortalToFollowElem >
-    </>
+          <div className='p-4 pt-3 border-t-[0.5px] border-t-black/5'>
+            <SuggestedAction disabled={!publishedAt} link={appURL} icon={<PlayCircle />}>{t('workflow.common.runApp')}</SuggestedAction>
+            {appDetail?.mode === 'workflow'
+              ? (
+                <SuggestedAction
+                  disabled={!publishedAt}
+                  link={`${appURL}${appURL.includes('?') ? '&' : '?'}mode=batch`}
+                  icon={<LeftIndent02 className='w-4 h-4' />}
+                >
+                  {t('workflow.common.batchRunApp')}
+                </SuggestedAction>
+              )
+              : (
+                <SuggestedAction
+                  onClick={() => {
+                    setEmbeddingModalOpen(true)
+                    handleTrigger()
+                  }}
+                  disabled={!publishedAt}
+                  icon={<CodeBrowser className='w-4 h-4' />}
+                >
+                  {t('workflow.common.embedIntoSite')}
+                </SuggestedAction>
+              )}
+            <SuggestedAction
+              onClick={() => {
+                handleOpenInExplore()
+              }}
+              disabled={!publishedAt}
+              icon={<RiPlanetLine className='w-4 h-4' />}
+            >
+              {t('workflow.common.openInExplore')}
+            </SuggestedAction>
+            <SuggestedAction disabled={!publishedAt} link='./develop' icon={<FileText className='w-4 h-4' />}>{t('workflow.common.accessAPIReference')}</SuggestedAction>
+            {appDetail?.mode === 'workflow' && (
+              <WorkflowToolConfigureButton
+                disabled={!publishedAt}
+                published={!!toolPublished}
+                detailNeedUpdate={!!toolPublished && published}
+                workflowAppId={appDetail?.id}
+                icon={{
+                  content: (appDetail.icon_type === 'image' ? '馃' : appDetail?.icon) || '馃',
+                  background: (appDetail.icon_type === 'image' ? appDefaultIconBackground : appDetail?.icon_background) || appDefaultIconBackground,
+                }}
+                name={appDetail?.name}
+                description={appDetail?.description}
+                inputs={inputs}
+                handlePublish={handlePublish}
+                onRefreshData={onRefreshData}
+              />
+            )}
+          </div>
+        </div>
+      </PortalToFollowElemContent>
+      <EmbeddedModal
+        siteInfo={appDetail?.site}
+        isShow={embeddingModalOpen}
+        onClose={() => setEmbeddingModalOpen(false)}
+        appBaseUrl={appBaseURL}
+        accessToken={accessToken}
+      />
+    </PortalToFollowElem >
   )
 }
 

--
Gitblit v1.8.0