mirror of
https://github.com/langgenius/dify.git
synced 2026-04-20 10:47:21 +08:00
feat: handle upgrade confirm and icon
This commit is contained in:
66
web/app/components/base/upgrade-modal/index.tsx
Normal file
66
web/app/components/base/upgrade-modal/index.tsx
Normal file
@ -0,0 +1,66 @@
|
||||
'use client'
|
||||
|
||||
import type { ComponentType, FC, ReactNode, SVGProps } from 'react'
|
||||
import Modal from '@/app/components/base/modal'
|
||||
import styles from './style.module.css'
|
||||
|
||||
type Props = {
|
||||
Icon?: ComponentType<SVGProps<SVGSVGElement>>
|
||||
title: string
|
||||
description: string
|
||||
extraInfo?: ReactNode
|
||||
footer?: ReactNode
|
||||
show: boolean
|
||||
onClose: () => void
|
||||
}
|
||||
|
||||
const UpgradeModalBase: FC<Props> = ({
|
||||
Icon,
|
||||
title,
|
||||
description,
|
||||
extraInfo,
|
||||
footer,
|
||||
show,
|
||||
onClose,
|
||||
}) => {
|
||||
return (
|
||||
<Modal
|
||||
isShow={show}
|
||||
onClose={onClose}
|
||||
closable={false}
|
||||
clickOutsideNotClose
|
||||
className={`${styles.surface} w-[580px] rounded-2xl !p-0`}
|
||||
>
|
||||
<div className="relative">
|
||||
<div
|
||||
aria-hidden
|
||||
className={`${styles.heroOverlay} pointer-events-none absolute inset-0`}
|
||||
/>
|
||||
<div className="px-8 pt-8">
|
||||
{Icon && (
|
||||
<div className={`${styles.icon} flex size-12 items-center justify-center rounded-xl shadow-lg backdrop-blur-[5px]`}>
|
||||
<Icon className="size-6 text-text-primary-on-surface" />
|
||||
</div>
|
||||
)}
|
||||
<div className="mt-6 space-y-2">
|
||||
<div className={`${styles.highlight} title-3xl-semi-bold`}>
|
||||
{title}
|
||||
</div>
|
||||
<div className="system-md-regular text-text-tertiary">
|
||||
{description}
|
||||
</div>
|
||||
</div>
|
||||
{extraInfo}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{footer && (
|
||||
<div className="mb-8 mt-10 flex justify-end space-x-2 px-8">
|
||||
{footer}
|
||||
</div>
|
||||
)}
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default UpgradeModalBase
|
||||
@ -4,11 +4,10 @@ import * as React from 'react'
|
||||
import { useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Button from '@/app/components/base/button'
|
||||
import Modal from '@/app/components/base/modal'
|
||||
import UpgradeModalBase from '@/app/components/base/upgrade-modal'
|
||||
import UpgradeBtn from '@/app/components/billing/upgrade-btn'
|
||||
import { useModalContext } from '@/context/modal-context'
|
||||
import { SquareChecklist } from '../../base/icons/src/vender/other'
|
||||
import styles from './style.module.css'
|
||||
|
||||
type Props = {
|
||||
Icon?: React.ComponentType<React.SVGProps<SVGSVGElement>>
|
||||
@ -41,50 +40,30 @@ const PlanUpgradeModal: FC<Props> = ({
|
||||
}, [onClose, onUpgrade, setShowPricingModal])
|
||||
|
||||
return (
|
||||
<Modal
|
||||
isShow={show}
|
||||
<UpgradeModalBase
|
||||
show={show}
|
||||
onClose={onClose}
|
||||
closable={false}
|
||||
clickOutsideNotClose
|
||||
className={`${styles.surface} w-[580px] rounded-2xl !p-0`}
|
||||
>
|
||||
<div className="relative">
|
||||
<div
|
||||
aria-hidden
|
||||
className={`${styles.heroOverlay} pointer-events-none absolute inset-0`}
|
||||
/>
|
||||
<div className="px-8 pt-8">
|
||||
<div className={`${styles.icon} flex size-12 items-center justify-center rounded-xl shadow-lg backdrop-blur-[5px]`}>
|
||||
<Icon className="size-6 text-text-primary-on-surface" />
|
||||
</div>
|
||||
<div className="mt-6 space-y-2">
|
||||
<div className={`${styles.highlight} title-3xl-semi-bold`}>
|
||||
{title}
|
||||
</div>
|
||||
<div className="system-md-regular text-text-tertiary">
|
||||
{description}
|
||||
</div>
|
||||
</div>
|
||||
{extraInfo}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mb-8 mt-10 flex justify-end space-x-2 px-8">
|
||||
<Button
|
||||
onClick={onClose}
|
||||
>
|
||||
{t('triggerLimitModal.dismiss', { ns: 'billing' })}
|
||||
</Button>
|
||||
<UpgradeBtn
|
||||
size="custom"
|
||||
isShort
|
||||
onClick={handleUpgrade}
|
||||
className="!h-8 !rounded-lg px-2"
|
||||
labelKey="triggerLimitModal.upgrade"
|
||||
loc="trigger-events-limit-modal"
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
// eslint-disable-next-line ts/no-explicit-any
|
||||
Icon={Icon as any}
|
||||
title={title}
|
||||
description={description}
|
||||
extraInfo={extraInfo}
|
||||
footer={(
|
||||
<>
|
||||
<Button onClick={onClose}>
|
||||
{t('triggerLimitModal.dismiss', { ns: 'billing' })}
|
||||
</Button>
|
||||
<UpgradeBtn
|
||||
size="custom"
|
||||
isShort
|
||||
onClick={handleUpgrade}
|
||||
className="!h-8 !rounded-lg px-2"
|
||||
labelKey="triggerLimitModal.upgrade"
|
||||
loc="trigger-events-limit-modal"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import { forwardRef, useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Button from '@/app/components/base/button'
|
||||
import { Thinking as ThinkingIcon } from '@/app/components/base/icons/src/vender/workflow'
|
||||
import UpgradeModalBase from '@/app/components/base/upgrade-modal'
|
||||
|
||||
const Thinking = forwardRef<SVGSVGElement, React.SVGProps<SVGSVGElement>>((props, ref) => (
|
||||
// eslint-disable-next-line ts/no-explicit-any
|
||||
<ThinkingIcon {...props} ref={ref as any} />
|
||||
))
|
||||
|
||||
type Props = {
|
||||
show: boolean
|
||||
onClose: () => void
|
||||
onUpgrade?: () => void
|
||||
}
|
||||
|
||||
const SandboxMigrationModal: FC<Props> = ({
|
||||
show,
|
||||
onClose,
|
||||
onUpgrade,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const handleUpgrade = useCallback(() => {
|
||||
onClose()
|
||||
onUpgrade?.()
|
||||
}, [onClose, onUpgrade])
|
||||
|
||||
return (
|
||||
<UpgradeModalBase
|
||||
show={show}
|
||||
onClose={onClose}
|
||||
Icon={Thinking}
|
||||
title={t('sandboxMigrationModal.title', { ns: 'workflow' })}
|
||||
description={t('sandboxMigrationModal.description', { ns: 'workflow' })}
|
||||
footer={(
|
||||
<>
|
||||
<Button onClick={onClose}>
|
||||
{t('sandboxMigrationModal.dismiss', { ns: 'workflow' })}
|
||||
</Button>
|
||||
<Button variant="primary" onClick={handleUpgrade}>
|
||||
{t('sandboxMigrationModal.upgrade', { ns: 'workflow' })}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default SandboxMigrationModal
|
||||
@ -13,12 +13,10 @@ import {
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
import { FeaturesProvider } from '@/app/components/base/features'
|
||||
import Loading from '@/app/components/base/loading'
|
||||
import { FILE_EXTS } from '@/app/components/base/prompt-editor/constants'
|
||||
import PlanUpgradeModal from '@/app/components/billing/plan-upgrade-modal'
|
||||
import WorkflowWithDefaultContext from '@/app/components/workflow'
|
||||
import { useCollaboration } from '@/app/components/workflow/collaboration'
|
||||
import { collaborationManager } from '@/app/components/workflow/collaboration/core/collaboration-manager'
|
||||
@ -42,6 +40,7 @@ import { useAppTriggers } from '@/service/use-tools'
|
||||
import { AppModeEnum } from '@/types/app'
|
||||
import { useFeatures } from '../base/features/hooks'
|
||||
import ViewPicker from '../workflow/view-picker'
|
||||
import SandboxMigrationModal from './components/sandbox-migration-modal'
|
||||
import WorkflowAppMain from './components/workflow-main'
|
||||
import { useGetRunAndTraceUrl } from './hooks/use-get-run-and-trace-url'
|
||||
import { useNodesSyncDraft } from './hooks/use-nodes-sync-draft'
|
||||
@ -173,7 +172,6 @@ const WorkflowAppWithAdditionalContext = () => {
|
||||
} = useWorkflowInit()
|
||||
const workflowStore = useWorkflowStore()
|
||||
const { isLoadingCurrentWorkspace, currentWorkspace } = useAppContext()
|
||||
const { t } = useTranslation()
|
||||
const [showMigrationModal, setShowMigrationModal] = useState(false)
|
||||
const lastCheckedAppIdRef = useRef<string | null>(null)
|
||||
|
||||
@ -366,11 +364,9 @@ const WorkflowAppWithAdditionalContext = () => {
|
||||
return (
|
||||
<>
|
||||
<CollaborationSession />
|
||||
<PlanUpgradeModal
|
||||
<SandboxMigrationModal
|
||||
show={showMigrationModal}
|
||||
onClose={handleCloseMigrationModal}
|
||||
title={t('sandboxMigrationModal.title', { ns: 'workflow' })}
|
||||
description={t('sandboxMigrationModal.description', { ns: 'workflow' })}
|
||||
/>
|
||||
<WorkflowWithDefaultContext
|
||||
edges={edgesData}
|
||||
|
||||
@ -1055,7 +1055,9 @@
|
||||
"publishLimit.startNodeTitlePrefix": "Upgrade to",
|
||||
"publishLimit.startNodeTitleSuffix": "unlock unlimited triggers per workflow",
|
||||
"sandboxMigrationModal.description": "This will create a separate copy of your app, without affecting the original.",
|
||||
"sandboxMigrationModal.dismiss": "Dismiss",
|
||||
"sandboxMigrationModal.title": "Upgrade to filesystem-based agents",
|
||||
"sandboxMigrationModal.upgrade": "Clone & Upgrade",
|
||||
"sidebar.exportWarning": "Export Current Saved Version",
|
||||
"sidebar.exportWarningDesc": "This will export the current saved version of your workflow. If you have unsaved changes in the editor, please save them first by using the export option in the workflow canvas.",
|
||||
"singleRun.back": "Back",
|
||||
|
||||
@ -1047,7 +1047,9 @@
|
||||
"publishLimit.startNodeTitlePrefix": "升级以",
|
||||
"publishLimit.startNodeTitleSuffix": "解锁每个工作流无限制的触发器",
|
||||
"sandboxMigrationModal.description": "这将创建你的应用的一个独立副本,不会影响原应用。",
|
||||
"sandboxMigrationModal.dismiss": "暂不升级",
|
||||
"sandboxMigrationModal.title": "升级到基于文件系统的智能体",
|
||||
"sandboxMigrationModal.upgrade": "复制并升级",
|
||||
"sidebar.exportWarning": "导出当前已保存版本",
|
||||
"sidebar.exportWarningDesc": "这将导出您工作流的当前已保存版本。如果您在编辑器中有未保存的更改,请先使用工作流画布中的导出选项保存它们。",
|
||||
"singleRun.back": "返回",
|
||||
|
||||
@ -1025,7 +1025,9 @@
|
||||
"publishLimit.startNodeTitlePrefix": "升級以",
|
||||
"publishLimit.startNodeTitleSuffix": "解鎖無限開始節點",
|
||||
"sandboxMigrationModal.description": "這將建立您的應用程式的獨立副本,不會影響原應用程式。",
|
||||
"sandboxMigrationModal.dismiss": "暫不升級",
|
||||
"sandboxMigrationModal.title": "升級到基於檔案系統的智能體",
|
||||
"sandboxMigrationModal.upgrade": "複製並升級",
|
||||
"sidebar.exportWarning": "導出當前保存的版本",
|
||||
"sidebar.exportWarningDesc": "這將導出當前保存的工作流程版本。如果您在編輯器中有未保存的更改,請先通過使用工作流程畫布中的導出選項來保存它們。",
|
||||
"singleRun.back": "返回",
|
||||
|
||||
Reference in New Issue
Block a user