| import { Lock01 } from '@/app/components/base/icons/src/vender/solid/security' | import { Lock01 } from '@/app/components/base/icons/src/vender/solid/security' | ||||
| import Button from '@/app/components/base/button' | import Button from '@/app/components/base/button' | ||||
| import { LinkExternal02 } from '@/app/components/base/icons/src/vender/line/general' | import { LinkExternal02 } from '@/app/components/base/icons/src/vender/line/general' | ||||
| import ConfirmUi from '@/app/components/base/confirm' | |||||
| import Confirm from '@/app/components/base/confirm' | |||||
| import { addTracingConfig, removeTracingConfig, updateTracingConfig } from '@/service/apps' | import { addTracingConfig, removeTracingConfig, updateTracingConfig } from '@/service/apps' | ||||
| import Toast from '@/app/components/base/toast' | import Toast from '@/app/components/base/toast' | ||||
| </PortalToFollowElem> | </PortalToFollowElem> | ||||
| ) | ) | ||||
| : ( | : ( | ||||
| <ConfirmUi | |||||
| <Confirm | |||||
| isShow | isShow | ||||
| onClose={hideRemoveConfirm} | |||||
| type='warning' | type='warning' | ||||
| title={t(`${I18N_PREFIX}.removeConfirmTitle`, { key: t(`app.tracing.${type}.title`) })!} | title={t(`${I18N_PREFIX}.removeConfirmTitle`, { key: t(`app.tracing.${type}.title`) })!} | ||||
| content={t(`${I18N_PREFIX}.removeConfirmContent`)} | content={t(`${I18N_PREFIX}.removeConfirmContent`)} |
| title={t('app.deleteAppConfirmTitle')} | title={t('app.deleteAppConfirmTitle')} | ||||
| content={t('app.deleteAppConfirmContent')} | content={t('app.deleteAppConfirmContent')} | ||||
| isShow={showConfirmDelete} | isShow={showConfirmDelete} | ||||
| onClose={() => setShowConfirmDelete(false)} | |||||
| onConfirm={onConfirmDelete} | onConfirm={onConfirmDelete} | ||||
| onCancel={() => setShowConfirmDelete(false)} | onCancel={() => setShowConfirmDelete(false)} | ||||
| /> | /> |
| title={t('dataset.deleteDatasetConfirmTitle')} | title={t('dataset.deleteDatasetConfirmTitle')} | ||||
| content={confirmMessage} | content={confirmMessage} | ||||
| isShow={showConfirmDelete} | isShow={showConfirmDelete} | ||||
| onClose={() => setShowConfirmDelete(false)} | |||||
| onConfirm={onConfirmDelete} | onConfirm={onConfirmDelete} | ||||
| onCancel={() => setShowConfirmDelete(false)} | onCancel={() => setShowConfirmDelete(false)} | ||||
| /> | /> |
| title={t('app.deleteAppConfirmTitle')} | title={t('app.deleteAppConfirmTitle')} | ||||
| content={t('app.deleteAppConfirmContent')} | content={t('app.deleteAppConfirmContent')} | ||||
| isShow={showConfirmDelete} | isShow={showConfirmDelete} | ||||
| onClose={() => setShowConfirmDelete(false)} | |||||
| onConfirm={onConfirmDelete} | onConfirm={onConfirmDelete} | ||||
| onCancel={() => setShowConfirmDelete(false)} | onCancel={() => setShowConfirmDelete(false)} | ||||
| /> | /> |
| import EditItem, { EditItemType } from './edit-item' | import EditItem, { EditItemType } from './edit-item' | ||||
| import Drawer from '@/app/components/base/drawer-plus' | import Drawer from '@/app/components/base/drawer-plus' | ||||
| import { MessageCheckRemove } from '@/app/components/base/icons/src/vender/line/communication' | import { MessageCheckRemove } from '@/app/components/base/icons/src/vender/line/communication' | ||||
| import DeleteConfirmModal from '@/app/components/base/modal/delete-confirm-modal' | |||||
| import Confirm from '@/app/components/base/confirm' | |||||
| import { addAnnotation, editAnnotation } from '@/service/annotation' | import { addAnnotation, editAnnotation } from '@/service/annotation' | ||||
| import Toast from '@/app/components/base/toast' | import Toast from '@/app/components/base/toast' | ||||
| import { useProviderContext } from '@/context/provider-context' | import { useProviderContext } from '@/context/provider-context' | ||||
| maxWidthClassName='!max-w-[480px]' | maxWidthClassName='!max-w-[480px]' | ||||
| title={t('appAnnotation.editModal.title') as string} | title={t('appAnnotation.editModal.title') as string} | ||||
| body={( | body={( | ||||
| <div className='p-6 pb-4 space-y-6'> | |||||
| <EditItem | |||||
| type={EditItemType.Query} | |||||
| content={query} | |||||
| readonly={(isAdd && isAnnotationFull) || onlyEditResponse} | |||||
| onSave={editedContent => handleSave(EditItemType.Query, editedContent)} | |||||
| /> | |||||
| <EditItem | |||||
| type={EditItemType.Answer} | |||||
| content={answer} | |||||
| readonly={isAdd && isAnnotationFull} | |||||
| onSave={editedContent => handleSave(EditItemType.Answer, editedContent)} | |||||
| /> | |||||
| <div> | |||||
| <div className='p-6 pb-4 space-y-6'> | |||||
| <EditItem | |||||
| type={EditItemType.Query} | |||||
| content={query} | |||||
| readonly={(isAdd && isAnnotationFull) || onlyEditResponse} | |||||
| onSave={editedContent => handleSave(EditItemType.Query, editedContent)} | |||||
| /> | |||||
| <EditItem | |||||
| type={EditItemType.Answer} | |||||
| content={answer} | |||||
| readonly={isAdd && isAnnotationFull} | |||||
| onSave={editedContent => handleSave(EditItemType.Answer, editedContent)} | |||||
| /> | |||||
| <Confirm | |||||
| isShow={showModal} | |||||
| onCancel={() => setShowModal(false)} | |||||
| onConfirm={() => { | |||||
| onRemove() | |||||
| setShowModal(false) | |||||
| onHide() | |||||
| }} | |||||
| title={t('appDebug.feature.annotation.removeConfirm')} | |||||
| /> | |||||
| </div> | |||||
| </div> | </div> | ||||
| )} | )} | ||||
| foot={ | foot={ | ||||
| </div> | </div> | ||||
| } | } | ||||
| /> | /> | ||||
| <DeleteConfirmModal | |||||
| isShow={showModal} | |||||
| onHide={() => setShowModal(false)} | |||||
| onRemove={() => { | |||||
| onRemove() | |||||
| setShowModal(false) | |||||
| onHide() | |||||
| }} | |||||
| text={t('appDebug.feature.annotation.removeConfirm') as string} | |||||
| /> | |||||
| </div> | </div> | ||||
| ) | ) |
| import type { FC } from 'react' | import type { FC } from 'react' | ||||
| import React from 'react' | import React from 'react' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import DeleteConfirmModal from '@/app/components/base/modal/delete-confirm-modal' | |||||
| import Confirm from '@/app/components/base/confirm' | |||||
| type Props = { | type Props = { | ||||
| isShow: boolean | isShow: boolean | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| return ( | return ( | ||||
| <DeleteConfirmModal | |||||
| <Confirm | |||||
| isShow={isShow} | isShow={isShow} | ||||
| onHide={onHide} | |||||
| onRemove={onRemove} | |||||
| text={t('appDebug.feature.annotation.removeConfirm') as string} | |||||
| onCancel={onHide} | |||||
| onConfirm={onRemove} | |||||
| title={t('appDebug.feature.annotation.removeConfirm')} | |||||
| /> | /> | ||||
| ) | ) | ||||
| } | } |
| import cn from '@/utils/classnames' | import cn from '@/utils/classnames' | ||||
| import Drawer from '@/app/components/base/drawer-plus' | import Drawer from '@/app/components/base/drawer-plus' | ||||
| import { MessageCheckRemove } from '@/app/components/base/icons/src/vender/line/communication' | import { MessageCheckRemove } from '@/app/components/base/icons/src/vender/line/communication' | ||||
| import DeleteConfirmModal from '@/app/components/base/modal/delete-confirm-modal' | |||||
| import Confirm from '@/app/components/base/confirm' | |||||
| import TabSlider from '@/app/components/base/tab-slider-plain' | import TabSlider from '@/app/components/base/tab-slider-plain' | ||||
| import { fetchHitHistoryList } from '@/service/annotation' | import { fetchHitHistoryList } from '@/service/annotation' | ||||
| import { APP_PAGE_LIMIT } from '@/config' | import { APP_PAGE_LIMIT } from '@/config' | ||||
| /> | /> | ||||
| } | } | ||||
| body={( | body={( | ||||
| <div className='p-6 pb-4 space-y-6'> | |||||
| {activeTab === TabType.annotation ? annotationTab : hitHistoryTab} | |||||
| <div> | |||||
| <div className='p-6 pb-4 space-y-6'> | |||||
| {activeTab === TabType.annotation ? annotationTab : hitHistoryTab} | |||||
| </div> | |||||
| <Confirm | |||||
| isShow={showModal} | |||||
| onCancel={() => setShowModal(false)} | |||||
| onConfirm={async () => { | |||||
| await onRemove() | |||||
| setShowModal(false) | |||||
| onHide() | |||||
| }} | |||||
| title={t('appDebug.feature.annotation.removeConfirm')} | |||||
| /> | |||||
| </div> | </div> | ||||
| )} | )} | ||||
| foot={id | foot={id | ||||
| ) | ) | ||||
| : undefined} | : undefined} | ||||
| /> | /> | ||||
| <DeleteConfirmModal | |||||
| isShow={showModal} | |||||
| onHide={() => setShowModal(false)} | |||||
| onRemove={async () => { | |||||
| await onRemove() | |||||
| setShowModal(false) | |||||
| onHide() | |||||
| }} | |||||
| text={t('appDebug.feature.annotation.removeConfirm') as string} | |||||
| /> | |||||
| </div> | </div> | ||||
| ) | ) |
| import Switch from '@/app/components/base/switch' | import Switch from '@/app/components/base/switch' | ||||
| import Toast from '@/app/components/base/toast' | import Toast from '@/app/components/base/toast' | ||||
| import { Settings01 } from '@/app/components/base/icons/src/vender/line/general' | import { Settings01 } from '@/app/components/base/icons/src/vender/line/general' | ||||
| import ConfirmModal from '@/app/components/base/confirm/common' | |||||
| import Confirm from '@/app/components/base/confirm' | |||||
| import ConfigContext from '@/context/debug-configuration' | import ConfigContext from '@/context/debug-configuration' | ||||
| import { AppType } from '@/types/app' | import { AppType } from '@/types/app' | ||||
| import type { ExternalDataTool } from '@/models/common' | import type { ExternalDataTool } from '@/models/common' | ||||
| )} | )} | ||||
| {isShowDeleteContextVarModal && ( | {isShowDeleteContextVarModal && ( | ||||
| <ConfirmModal | |||||
| <Confirm | |||||
| isShow={isShowDeleteContextVarModal} | isShow={isShowDeleteContextVarModal} | ||||
| title={t('appDebug.feature.dataSet.queryVariable.deleteContextVarTitle', { varName: promptVariables[removeIndex as number]?.name })} | title={t('appDebug.feature.dataSet.queryVariable.deleteContextVarTitle', { varName: promptVariables[removeIndex as number]?.name })} | ||||
| desc={t('appDebug.feature.dataSet.queryVariable.deleteContextVarTip') as string} | |||||
| confirmBtnClassName='bg-[#B42318] hover:bg-[#B42318]' | |||||
| content={t('appDebug.feature.dataSet.queryVariable.deleteContextVarTip')} | |||||
| onConfirm={() => { | onConfirm={() => { | ||||
| didRemoveVar(removeIndex as number) | didRemoveVar(removeIndex as number) | ||||
| hideDeleteContextVarModal() | hideDeleteContextVarModal() |
| title={t('appDebug.generate.overwriteTitle')} | title={t('appDebug.generate.overwriteTitle')} | ||||
| content={t('appDebug.generate.overwriteMessage')} | content={t('appDebug.generate.overwriteMessage')} | ||||
| isShow={showConfirmOverwrite} | isShow={showConfirmOverwrite} | ||||
| onClose={() => setShowConfirmOverwrite(false)} | |||||
| onConfirm={() => { | onConfirm={() => { | ||||
| setShowConfirmOverwrite(false) | setShowConfirmOverwrite(false) | ||||
| onFinished(res!) | onFinished(res!) |
| title={t('appDebug.resetConfig.title')} | title={t('appDebug.resetConfig.title')} | ||||
| content={t('appDebug.resetConfig.message')} | content={t('appDebug.resetConfig.message')} | ||||
| isShow={restoreConfirmOpen} | isShow={restoreConfirmOpen} | ||||
| onClose={() => setRestoreConfirmOpen(false)} | |||||
| onConfirm={resetAppConfig} | onConfirm={resetAppConfig} | ||||
| onCancel={() => setRestoreConfirmOpen(false)} | onCancel={() => setRestoreConfirmOpen(false)} | ||||
| /> | /> | ||||
| title={t('appDebug.trailUseGPT4Info.title')} | title={t('appDebug.trailUseGPT4Info.title')} | ||||
| content={t('appDebug.trailUseGPT4Info.description')} | content={t('appDebug.trailUseGPT4Info.description')} | ||||
| isShow={showUseGPT4Confirm} | isShow={showUseGPT4Confirm} | ||||
| onClose={() => setShowUseGPT4Confirm(false)} | |||||
| onConfirm={() => { | onConfirm={() => { | ||||
| setShowAccountSettingModal({ payload: 'provider' }) | setShowAccountSettingModal({ payload: 'provider' }) | ||||
| setShowUseGPT4Confirm(false) | setShowUseGPT4Confirm(false) |
| title={t('appOverview.overview.appInfo.regenerate')} | title={t('appOverview.overview.appInfo.regenerate')} | ||||
| content={t('appOverview.overview.appInfo.regenerateNotice')} | content={t('appOverview.overview.appInfo.regenerateNotice')} | ||||
| isShow={showConfirmDelete} | isShow={showConfirmDelete} | ||||
| onClose={() => setShowConfirmDelete(false)} | |||||
| onConfirm={() => { | onConfirm={() => { | ||||
| onGenCode() | onGenCode() | ||||
| setShowConfirmDelete(false) | setShowConfirmDelete(false) |
| setShowConfirmDelete(false) | setShowConfirmDelete(false) | ||||
| setRemoveOriginal(false) | setRemoveOriginal(false) | ||||
| }} | }} | ||||
| onClose={() => { | |||||
| setShowConfirmDelete(false) | |||||
| setRemoveOriginal(false) | |||||
| }} | |||||
| /> | /> | ||||
| )} | )} | ||||
| </> | </> |
| title={t('share.chat.deleteConversation.title')} | title={t('share.chat.deleteConversation.title')} | ||||
| content={t('share.chat.deleteConversation.content') || ''} | content={t('share.chat.deleteConversation.content') || ''} | ||||
| isShow | isShow | ||||
| onClose={handleCancelConfirm} | |||||
| onCancel={handleCancelConfirm} | onCancel={handleCancelConfirm} | ||||
| onConfirm={handleDelete} | onConfirm={handleDelete} | ||||
| /> | /> |
| 'use client' | |||||
| import type { FC } from 'react' | |||||
| import React from 'react' | |||||
| import { useTranslation } from 'react-i18next' | |||||
| import Button from '../button' | |||||
| export type IConfirmUIProps = { | |||||
| type: 'info' | 'warning' | |||||
| title: string | |||||
| content: string | |||||
| confirmText?: string | |||||
| onConfirm: () => void | |||||
| cancelText?: string | |||||
| onCancel: () => void | |||||
| } | |||||
| const ConfirmUI: FC<IConfirmUIProps> = ({ | |||||
| type, | |||||
| title, | |||||
| content, | |||||
| confirmText, | |||||
| cancelText, | |||||
| onConfirm, | |||||
| onCancel, | |||||
| }) => { | |||||
| const { t } = useTranslation() | |||||
| return ( | |||||
| <div className="w-[420px] max-w-full rounded-lg p-7 bg-white"> | |||||
| <div className='flex items-center'> | |||||
| {type === 'info' && (<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path d="M17.3333 21.3333H16V16H14.6667M16 10.6667H16.0133M28 16C28 17.5759 27.6896 19.1363 27.0866 20.5922C26.4835 22.0481 25.5996 23.371 24.4853 24.4853C23.371 25.5996 22.0481 26.4835 20.5922 27.0866C19.1363 27.6896 17.5759 28 16 28C14.4241 28 12.8637 27.6896 11.4078 27.0866C9.95189 26.4835 8.62902 25.5996 7.51472 24.4853C6.40042 23.371 5.5165 22.0481 4.91345 20.5922C4.31039 19.1363 4 17.5759 4 16C4 12.8174 5.26428 9.76516 7.51472 7.51472C9.76516 5.26428 12.8174 4 16 4C19.1826 4 22.2348 5.26428 24.4853 7.51472C26.7357 9.76516 28 12.8174 28 16Z" stroke="#9CA3AF" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" /> | |||||
| </svg>)} | |||||
| {type === 'warning' && (<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path d="M16 10.6667V16M16 21.3333H16.0133M28 16C28 17.5759 27.6896 19.1363 27.0866 20.5922C26.4835 22.0481 25.5996 23.371 24.4853 24.4853C23.371 25.5996 22.0481 26.4835 20.5922 27.0866C19.1363 27.6896 17.5759 28 16 28C14.4241 28 12.8637 27.6896 11.4078 27.0866C9.95189 26.4835 8.62902 25.5996 7.51472 24.4853C6.40042 23.371 5.5165 22.0481 4.91345 20.5922C4.31039 19.1363 4 17.5759 4 16C4 12.8174 5.26428 9.76516 7.51472 7.51472C9.76516 5.26428 12.8174 4 16 4C19.1826 4 22.2348 5.26428 24.4853 7.51472C26.7357 9.76516 28 12.8174 28 16Z" stroke="#FACA15" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" /> | |||||
| </svg> | |||||
| )} | |||||
| <div className='ml-4 text-lg text-gray-900'>{title}</div> | |||||
| </div> | |||||
| <div className='mt-1 ml-12'> | |||||
| <div className='text-sm leading-normal text-gray-500'>{content}</div> | |||||
| </div> | |||||
| <div className='flex gap-3 mt-4 ml-12'> | |||||
| <Button variant='primary' onClick={onConfirm}>{confirmText || t('common.operation.confirm')}</Button> | |||||
| <Button onClick={onCancel}>{cancelText || t('common.operation.cancel')}</Button> | |||||
| </div> | |||||
| </div> | |||||
| ) | |||||
| } | |||||
| export default React.memo(ConfirmUI) |
| .wrapper-danger { | |||||
| background: linear-gradient(180deg, rgba(217, 45, 32, 0.05) 0%, rgba(217, 45, 32, 0.00) 24.02%), #F9FAFB; | |||||
| } | |||||
| .wrapper-success { | |||||
| background: linear-gradient(180deg, rgba(3, 152, 85, 0.05) 0%, rgba(3, 152, 85, 0.00) 22.44%), #F9FAFB; | |||||
| } |
| import type { FC, ReactElement } from 'react' | |||||
| import { useTranslation } from 'react-i18next' | |||||
| import { | |||||
| RiCloseLine, | |||||
| RiErrorWarningFill, | |||||
| } from '@remixicon/react' | |||||
| import s from './common.module.css' | |||||
| import cn from '@/utils/classnames' | |||||
| import Modal from '@/app/components/base/modal' | |||||
| import { CheckCircle } from '@/app/components/base/icons/src/vender/solid/general' | |||||
| import Button from '@/app/components/base/button' | |||||
| export type ConfirmCommonProps = { | |||||
| type?: string | |||||
| isShow: boolean | |||||
| onCancel: () => void | |||||
| title: string | |||||
| desc?: string | |||||
| onConfirm?: () => void | |||||
| showOperate?: boolean | |||||
| showOperateCancel?: boolean | |||||
| confirmBtnClassName?: string | |||||
| confirmText?: string | |||||
| confirmWrapperClassName?: string | |||||
| confirmDisabled?: boolean | |||||
| } | |||||
| const ConfirmCommon: FC<ConfirmCommonProps> = ({ | |||||
| type = 'danger', | |||||
| isShow, | |||||
| onCancel, | |||||
| title, | |||||
| desc, | |||||
| onConfirm, | |||||
| showOperate = true, | |||||
| showOperateCancel = true, | |||||
| confirmBtnClassName, | |||||
| confirmText, | |||||
| confirmWrapperClassName, | |||||
| confirmDisabled, | |||||
| }) => { | |||||
| const { t } = useTranslation() | |||||
| const CONFIRM_MAP: Record<string, { icon: ReactElement; confirmText: string }> = { | |||||
| danger: { | |||||
| icon: <RiErrorWarningFill className='w-6 h-6 text-[#D92D20]' />, | |||||
| confirmText: t('common.operation.remove'), | |||||
| }, | |||||
| success: { | |||||
| icon: <CheckCircle className='w-6 h-6 text-[#039855]' />, | |||||
| confirmText: t('common.operation.ok'), | |||||
| }, | |||||
| } | |||||
| return ( | |||||
| <Modal isShow={isShow} onClose={() => { }} className='!w-[480px] !max-w-[480px] !p-0 !rounded-2xl' wrapperClassName={confirmWrapperClassName}> | |||||
| <div className={cn(s[`wrapper-${type}`], 'relative p-8')}> | |||||
| <div className='flex items-center justify-center absolute top-4 right-4 w-8 h-8 cursor-pointer' onClick={onCancel}> | |||||
| <RiCloseLine className='w-4 h-4 text-gray-500' /> | |||||
| </div> | |||||
| <div className='flex items-center justify-center mb-3 w-12 h-12 bg-white shadow-xl rounded-xl'> | |||||
| {CONFIRM_MAP[type].icon} | |||||
| </div> | |||||
| <div className='text-xl font-semibold text-gray-900'>{title}</div> | |||||
| { | |||||
| desc && <div className='mt-1 text-sm text-gray-500'>{desc}</div> | |||||
| } | |||||
| { | |||||
| showOperate && ( | |||||
| <div className='flex items-center justify-end mt-10'> | |||||
| { | |||||
| showOperateCancel && ( | |||||
| <Button | |||||
| className='mr-2' | |||||
| onClick={onCancel} | |||||
| > | |||||
| {t('common.operation.cancel')} | |||||
| </Button> | |||||
| ) | |||||
| } | |||||
| <Button | |||||
| variant='primary' | |||||
| className={confirmBtnClassName || ''} | |||||
| onClick={onConfirm} | |||||
| disabled={confirmDisabled} | |||||
| > | |||||
| {confirmText || CONFIRM_MAP[type].confirmText} | |||||
| </Button> | |||||
| </div> | |||||
| ) | |||||
| } | |||||
| </div> | |||||
| </Modal> | |||||
| ) | |||||
| } | |||||
| export default ConfirmCommon |
| import { Dialog, Transition } from '@headlessui/react' | |||||
| import { Fragment } from 'react' | |||||
| import React, { useEffect, useRef, useState } from 'react' | |||||
| import { createPortal } from 'react-dom' | |||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import ConfirmUI from '../confirm-ui' | |||||
| import Button from '../button' | |||||
| // https://headlessui.com/react/dialog | |||||
| type IConfirm = { | |||||
| export type IConfirm = { | |||||
| className?: string | className?: string | ||||
| isShow: boolean | isShow: boolean | ||||
| onClose: () => void | |||||
| type?: 'info' | 'warning' | type?: 'info' | 'warning' | ||||
| title: string | title: string | ||||
| content: string | |||||
| confirmText?: string | |||||
| content?: React.ReactNode | |||||
| confirmText?: string | null | |||||
| onConfirm: () => void | onConfirm: () => void | ||||
| cancelText?: string | cancelText?: string | ||||
| onCancel: () => void | onCancel: () => void | ||||
| isLoading?: boolean | |||||
| isDisabled?: boolean | |||||
| showConfirm?: boolean | |||||
| showCancel?: boolean | |||||
| maskClosable?: boolean | |||||
| } | } | ||||
| export default function Confirm({ | |||||
| function Confirm({ | |||||
| isShow, | isShow, | ||||
| onClose, | |||||
| type = 'warning', | type = 'warning', | ||||
| title, | title, | ||||
| content, | content, | ||||
| cancelText, | cancelText, | ||||
| onConfirm, | onConfirm, | ||||
| onCancel, | onCancel, | ||||
| showConfirm = true, | |||||
| showCancel = true, | |||||
| isLoading = false, | |||||
| isDisabled = false, | |||||
| maskClosable = true, | |||||
| }: IConfirm) { | }: IConfirm) { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const dialogRef = useRef<HTMLDivElement>(null) | |||||
| const [isVisible, setIsVisible] = useState(isShow) | |||||
| const confirmTxt = confirmText || `${t('common.operation.confirm')}` | const confirmTxt = confirmText || `${t('common.operation.confirm')}` | ||||
| const cancelTxt = cancelText || `${t('common.operation.cancel')}` | const cancelTxt = cancelText || `${t('common.operation.cancel')}` | ||||
| return ( | |||||
| <Transition appear show={isShow} as={Fragment}> | |||||
| <Dialog as="div" className="relative z-[100]" onClose={onClose} onClick={e => e.preventDefault()}> | |||||
| <Transition.Child | |||||
| as={Fragment} | |||||
| enter="ease-out duration-300" | |||||
| enterFrom="opacity-0" | |||||
| enterTo="opacity-100" | |||||
| leave="ease-in duration-200" | |||||
| leaveFrom="opacity-100" | |||||
| leaveTo="opacity-0" | |||||
| > | |||||
| <div className="fixed inset-0 bg-black bg-opacity-25" /> | |||||
| </Transition.Child> | |||||
| <div className="fixed inset-0 overflow-y-auto"> | |||||
| <div className="flex items-center justify-center min-h-full p-4 text-center"> | |||||
| <Transition.Child | |||||
| as={Fragment} | |||||
| enter="ease-out duration-300" | |||||
| enterFrom="opacity-0 scale-95" | |||||
| enterTo="opacity-100 scale-100" | |||||
| leave="ease-in duration-200" | |||||
| leaveFrom="opacity-100 scale-100" | |||||
| leaveTo="opacity-0 scale-95" | |||||
| > | |||||
| <Dialog.Panel className={'w-full max-w-md transform overflow-hidden rounded-2xl bg-white text-left align-middle shadow-xl transition-all'}> | |||||
| <ConfirmUI | |||||
| type={type} | |||||
| title={title} | |||||
| content={content} | |||||
| confirmText={confirmTxt} | |||||
| cancelText={cancelTxt} | |||||
| onConfirm={onConfirm} | |||||
| onCancel={onCancel} | |||||
| /> | |||||
| </Dialog.Panel> | |||||
| </Transition.Child> | |||||
| useEffect(() => { | |||||
| const handleKeyDown = (event: KeyboardEvent) => { | |||||
| if (event.key === 'Escape') | |||||
| onCancel() | |||||
| } | |||||
| document.addEventListener('keydown', handleKeyDown) | |||||
| return () => { | |||||
| document.removeEventListener('keydown', handleKeyDown) | |||||
| } | |||||
| }, [onCancel]) | |||||
| const handleClickOutside = (event: MouseEvent) => { | |||||
| if (maskClosable && dialogRef.current && !dialogRef.current.contains(event.target as Node)) | |||||
| onCancel() | |||||
| } | |||||
| useEffect(() => { | |||||
| document.addEventListener('mousedown', handleClickOutside) | |||||
| return () => { | |||||
| document.removeEventListener('mousedown', handleClickOutside) | |||||
| } | |||||
| }, [maskClosable]) | |||||
| useEffect(() => { | |||||
| if (isShow) { | |||||
| setIsVisible(true) | |||||
| } | |||||
| else { | |||||
| const timer = setTimeout(() => setIsVisible(false), 200) | |||||
| return () => clearTimeout(timer) | |||||
| } | |||||
| }, [isShow]) | |||||
| if (!isVisible) | |||||
| return null | |||||
| return createPortal( | |||||
| <div className={'fixed inset-0 flex items-center justify-center z-[10000000] bg-background-overlay'} | |||||
| onClick={(e) => { | |||||
| e.preventDefault() | |||||
| e.stopPropagation() | |||||
| }}> | |||||
| <div ref={dialogRef} className={'relative w-full max-w-[480px] overflow-hidden'}> | |||||
| <div className='flex flex-col items-start max-w-full rounded-2xl border-[0.5px] border-solid border-components-panel-border shadows-shadow-lg bg-components-panel-bg'> | |||||
| <div className='flex pt-6 pl-6 pr-6 pb-4 flex-col items-start gap-2 self-stretch'> | |||||
| <div className='title-2xl-semi-bold text-text-primary'>{title}</div> | |||||
| <div className='system-md-regular text-text-tertiary'>{content}</div> | |||||
| </div> | |||||
| <div className='flex p-6 gap-2 justify-end items-start self-stretch'> | |||||
| {showCancel && <Button onClick={onCancel}>{cancelTxt}</Button>} | |||||
| {showConfirm && <Button variant={'primary'} destructive={type !== 'info'} loading={isLoading} disabled={isDisabled} onClick={onConfirm}>{confirmTxt}</Button>} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </Dialog> | |||||
| </Transition> | |||||
| </div> | |||||
| </div>, document.body, | |||||
| ) | ) | ||||
| } | } | ||||
| export default React.memo(Confirm) |
| 'use client' | |||||
| import type { FC } from 'react' | |||||
| import React from 'react' | |||||
| import { useTranslation } from 'react-i18next' | |||||
| import { | |||||
| RiErrorWarningFill, | |||||
| } from '@remixicon/react' | |||||
| import s from './style.module.css' | |||||
| import Modal from '@/app/components/base/modal' | |||||
| import Button from '@/app/components/base/button' | |||||
| type Props = { | |||||
| isShow: boolean | |||||
| onHide: () => void | |||||
| onRemove: () => void | |||||
| text?: string | |||||
| children?: JSX.Element | |||||
| } | |||||
| const DeleteConfirmModal: FC<Props> = ({ | |||||
| isShow, | |||||
| onHide, | |||||
| onRemove, | |||||
| children, | |||||
| text, | |||||
| }) => { | |||||
| const { t } = useTranslation() | |||||
| if (!isShow) | |||||
| return null | |||||
| return ( | |||||
| <Modal | |||||
| isShow={isShow} | |||||
| onClose={onHide} | |||||
| className={s.delModal} | |||||
| closable | |||||
| > | |||||
| <div onClick={(e) => { | |||||
| e.stopPropagation() | |||||
| e.stopPropagation() | |||||
| e.nativeEvent.stopImmediatePropagation() | |||||
| }}> | |||||
| <div className={s.warningWrapper}> | |||||
| <RiErrorWarningFill className='w-6 h-6 text-red-600' /> | |||||
| </div> | |||||
| {text | |||||
| ? ( | |||||
| <div className='text-xl font-semibold text-gray-900 mb-3'>{text}</div> | |||||
| ) | |||||
| : children} | |||||
| <div className='flex gap-2 justify-end'> | |||||
| <Button onClick={onHide}>{t('common.operation.cancel')}</Button> | |||||
| <Button | |||||
| variant='warning' | |||||
| onClick={onRemove} | |||||
| className='border-red-700' | |||||
| > | |||||
| {t('common.operation.sure')} | |||||
| </Button> | |||||
| </div> | |||||
| </div> | |||||
| </Modal> | |||||
| ) | |||||
| } | |||||
| export default React.memo(DeleteConfirmModal) |
| .delModal { | |||||
| background: linear-gradient(180deg, | |||||
| rgba(217, 45, 32, 0.05) 0%, | |||||
| rgba(217, 45, 32, 0) 24.02%), | |||||
| #f9fafb; | |||||
| box-shadow: 0px 20px 24px -4px rgba(16, 24, 40, 0.08), | |||||
| 0px 8px 8px -4px rgba(16, 24, 40, 0.03); | |||||
| @apply rounded-2xl p-8; | |||||
| } | |||||
| .warningWrapper { | |||||
| box-shadow: 0px 20px 24px -4px rgba(16, 24, 40, 0.08), | |||||
| 0px 8px 8px -4px rgba(16, 24, 40, 0.03); | |||||
| background: rgba(255, 255, 255, 0.9); | |||||
| @apply h-12 w-12 border-[0.5px] border-gray-100 rounded-xl mb-3 flex items-center justify-center; | |||||
| } |
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { | import { | ||||
| RiDeleteBinLine, | RiDeleteBinLine, | ||||
| RiErrorWarningFill, | |||||
| } from '@remixicon/react' | } from '@remixicon/react' | ||||
| import { StatusItem } from '../../list' | import { StatusItem } from '../../list' | ||||
| import { DocumentTitle } from '../index' | import { DocumentTitle } from '../index' | ||||
| import s from './style.module.css' | import s from './style.module.css' | ||||
| import { SegmentIndexTag } from './index' | import { SegmentIndexTag } from './index' | ||||
| import cn from '@/utils/classnames' | import cn from '@/utils/classnames' | ||||
| import Modal from '@/app/components/base/modal' | |||||
| import Button from '@/app/components/base/button' | |||||
| import Confirm from '@/app/components/base/confirm' | |||||
| import Switch from '@/app/components/base/switch' | import Switch from '@/app/components/base/switch' | ||||
| import Divider from '@/app/components/base/divider' | import Divider from '@/app/components/base/divider' | ||||
| import Indicator from '@/app/components/header/indicator' | import Indicator from '@/app/components/header/indicator' | ||||
| </div> | </div> | ||||
| </> | </> | ||||
| )} | )} | ||||
| {showModal && <Modal isShow={showModal} onClose={() => setShowModal(false)} className={s.delModal} closable> | |||||
| <div> | |||||
| <div className={s.warningWrapper}> | |||||
| <RiErrorWarningFill className='w-6 h-6 text-red-600' /> | |||||
| </div> | |||||
| <div className='text-xl font-semibold text-gray-900 mb-1'>{t('datasetDocuments.segment.delete')}</div> | |||||
| <div className='flex gap-2 justify-end'> | |||||
| <Button onClick={() => setShowModal(false)}>{t('common.operation.cancel')}</Button> | |||||
| <Button | |||||
| variant='warning' | |||||
| onClick={async () => { | |||||
| await onDelete?.(id) | |||||
| }} | |||||
| className='border-red-700' | |||||
| > | |||||
| {t('common.operation.sure')} | |||||
| </Button> | |||||
| </div> | |||||
| </div> | |||||
| </Modal>} | |||||
| {showModal | |||||
| && <Confirm | |||||
| isShow={showModal} | |||||
| title={t('datasetDocuments.segment.delete')} | |||||
| confirmText={t('common.operation.sure')} | |||||
| onConfirm={async () => { await onDelete?.(id) }} | |||||
| onCancel={() => setShowModal(false)} | |||||
| /> | |||||
| } | |||||
| </div> | </div> | ||||
| ) | ) | ||||
| } | } |
| import React, { useCallback, useEffect, useState } from 'react' | import React, { useCallback, useEffect, useState } from 'react' | ||||
| import { useBoolean, useDebounceFn } from 'ahooks' | import { useBoolean, useDebounceFn } from 'ahooks' | ||||
| import { ArrowDownIcon, TrashIcon } from '@heroicons/react/24/outline' | import { ArrowDownIcon, TrashIcon } from '@heroicons/react/24/outline' | ||||
| import { ExclamationCircleIcon } from '@heroicons/react/24/solid' | |||||
| import { pick } from 'lodash-es' | import { pick } from 'lodash-es' | ||||
| import { | import { | ||||
| RiMoreFill, | RiMoreFill, | ||||
| import Switch from '@/app/components/base/switch' | import Switch from '@/app/components/base/switch' | ||||
| import Divider from '@/app/components/base/divider' | import Divider from '@/app/components/base/divider' | ||||
| import Popover from '@/app/components/base/popover' | import Popover from '@/app/components/base/popover' | ||||
| import Modal from '@/app/components/base/modal' | |||||
| import Button from '@/app/components/base/button' | |||||
| import Confirm from '@/app/components/base/confirm' | |||||
| import Tooltip from '@/app/components/base/tooltip' | import Tooltip from '@/app/components/base/tooltip' | ||||
| import { ToastContext } from '@/app/components/base/toast' | import { ToastContext } from '@/app/components/base/toast' | ||||
| import type { IndicatorProps } from '@/app/components/header/indicator' | import type { IndicatorProps } from '@/app/components/header/indicator' | ||||
| className={`flex justify-end !w-[200px] h-fit !z-20 ${className}`} | className={`flex justify-end !w-[200px] h-fit !z-20 ${className}`} | ||||
| /> | /> | ||||
| )} | )} | ||||
| {showModal && <Modal isShow={showModal} onClose={() => setShowModal(false)} className={s.delModal} closable> | |||||
| <div> | |||||
| <div className={s.warningWrapper}> | |||||
| <ExclamationCircleIcon className={s.warningIcon} /> | |||||
| </div> | |||||
| <div className='text-xl font-semibold text-gray-900 mb-1'>{t('datasetDocuments.list.delete.title')}</div> | |||||
| <div className='text-sm text-gray-500 mb-10'>{t('datasetDocuments.list.delete.content')}</div> | |||||
| <div className='flex gap-2 justify-end'> | |||||
| <Button onClick={() => setShowModal(false)}>{t('common.operation.cancel')}</Button> | |||||
| <Button | |||||
| variant='warning' | |||||
| onClick={() => onOperate('delete')} | |||||
| className='border-red-700' | |||||
| > | |||||
| {t('common.operation.sure')} | |||||
| </Button> | |||||
| </div> | |||||
| </div> | |||||
| </Modal>} | |||||
| {showModal | |||||
| && <Confirm | |||||
| isShow={showModal} | |||||
| title={t('datasetDocuments.list.delete.title')} | |||||
| content={t('datasetDocuments.list.delete.content')} | |||||
| confirmText={t('common.operation.sure')} | |||||
| onConfirm={() => onOperate('delete')} | |||||
| onCancel={() => setShowModal(false)} | |||||
| /> | |||||
| } | |||||
| {isShowRenameModal && currDocument && ( | {isShowRenameModal && currDocument && ( | ||||
| <RenameModal | <RenameModal |
| title={`${t('appApi.actionMsg.deleteConfirmTitle')}`} | title={`${t('appApi.actionMsg.deleteConfirmTitle')}`} | ||||
| content={`${t('appApi.actionMsg.deleteConfirmTips')}`} | content={`${t('appApi.actionMsg.deleteConfirmTips')}`} | ||||
| isShow={showConfirmDelete} | isShow={showConfirmDelete} | ||||
| onClose={() => { | |||||
| setDelKeyId('') | |||||
| setShowConfirmDelete(false) | |||||
| }} | |||||
| onConfirm={onDel} | onConfirm={onDel} | ||||
| onCancel={() => { | onCancel={() => { | ||||
| setDelKeyId('') | setDelKeyId('') |
| title={t('explore.sidebar.delete.title')} | title={t('explore.sidebar.delete.title')} | ||||
| content={t('explore.sidebar.delete.content')} | content={t('explore.sidebar.delete.content')} | ||||
| isShow={showConfirm} | isShow={showConfirm} | ||||
| onClose={() => setShowConfirm(false)} | |||||
| onConfirm={handleDelete} | onConfirm={handleDelete} | ||||
| onCancel={() => setShowConfirm(false)} | onCancel={() => setShowConfirm(false)} | ||||
| /> | /> |
| 'use client' | 'use client' | ||||
| import { useState } from 'react' | import { useState } from 'react' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { | |||||
| RiCloseLine, | |||||
| RiErrorWarningFill, | |||||
| } from '@remixicon/react' | |||||
| import { useContext } from 'use-context-selector' | import { useContext } from 'use-context-selector' | ||||
| import Collapse from '../collapse' | import Collapse from '../collapse' | ||||
| import type { IItem } from '../collapse' | import type { IItem } from '../collapse' | ||||
| import s from './index.module.css' | import s from './index.module.css' | ||||
| import classNames from '@/utils/classnames' | import classNames from '@/utils/classnames' | ||||
| import Modal from '@/app/components/base/modal' | import Modal from '@/app/components/base/modal' | ||||
| import Confirm from '@/app/components/base/confirm' | |||||
| import Button from '@/app/components/base/button' | import Button from '@/app/components/base/button' | ||||
| import { updateUserProfile } from '@/service/common' | import { updateUserProfile } from '@/service/common' | ||||
| import { useAppContext } from '@/context/app-context' | import { useAppContext } from '@/context/app-context' | ||||
| </Modal> | </Modal> | ||||
| )} | )} | ||||
| {showDeleteAccountModal && ( | {showDeleteAccountModal && ( | ||||
| <Modal | |||||
| className={classNames('p-8 max-w-[480px] w-[480px]', s.bg)} | |||||
| isShow={showDeleteAccountModal} | |||||
| onClose={() => { }} | |||||
| > | |||||
| <div className='absolute right-4 top-4 p-2 cursor-pointer' onClick={() => setShowDeleteAccountModal(false)}> | |||||
| <RiCloseLine className='w-4 h-4 text-gray-500' /> | |||||
| </div> | |||||
| <div className='w-12 h-12 p-3 bg-white rounded-xl border-[0.5px] border-gray-100 shadow-xl'> | |||||
| <RiErrorWarningFill className='w-6 h-6 text-[#D92D20]' /> | |||||
| </div> | |||||
| <div className='relative mt-3 text-xl font-semibold leading-[30px] text-gray-900'>{t('common.account.delete')}</div> | |||||
| <div className='my-1 text-[#D92D20] text-sm leading-5'> | |||||
| {t('common.account.deleteTip')} | |||||
| </div> | |||||
| <div className='mt-3 text-sm leading-5'> | |||||
| <span>{t('common.account.deleteConfirmTip')}</span> | |||||
| <a className='text-primary-600 cursor' href={`mailto:support@dify.ai?subject=Delete Account Request&body=Delete Account: ${userProfile.email}`} target='_blank'>support@dify.ai</a> | |||||
| </div> | |||||
| <div className='my-2 px-3 py-2 rounded-lg bg-gray-100 text-sm font-medium leading-5 text-gray-800'>{`Delete Account: ${userProfile.email}`}</div> | |||||
| <div className='pt-6 flex justify-end items-center'> | |||||
| <Button className='w-24' onClick={() => setShowDeleteAccountModal(false)}>{t('common.operation.ok')}</Button> | |||||
| </div> | |||||
| </Modal> | |||||
| <Confirm | |||||
| isShow | |||||
| onCancel={() => setShowDeleteAccountModal(false)} | |||||
| onConfirm={() => setShowDeleteAccountModal(false)} | |||||
| showCancel={false} | |||||
| type='warning' | |||||
| title={t('common.account.delete')} | |||||
| content={<> | |||||
| <div className='my-1 text-[#D92D20] text-sm leading-5'> | |||||
| {t('common.account.deleteTip')} | |||||
| </div> | |||||
| <div className='mt-3 text-sm leading-5'> | |||||
| <span>{t('common.account.deleteConfirmTip')}</span> | |||||
| <a className='text-primary-600 cursor' href={`mailto:support@dify.ai?subject=Delete Account Request&body=Delete Account: ${userProfile.email}`} target='_blank'>support@dify.ai</a> | |||||
| </div> | |||||
| </>} | |||||
| confirmText={t('common.operation.ok') as string} | |||||
| /> | |||||
| )} | )} | ||||
| </> | </> | ||||
| ) | ) |
| import type { ApiBasedExtension } from '@/models/common' | import type { ApiBasedExtension } from '@/models/common' | ||||
| import { useModalContext } from '@/context/modal-context' | import { useModalContext } from '@/context/modal-context' | ||||
| import { deleteApiBasedExtension } from '@/service/common' | import { deleteApiBasedExtension } from '@/service/common' | ||||
| import ConfirmCommon from '@/app/components/base/confirm/common' | |||||
| import Confirm from '@/app/components/base/confirm' | |||||
| type ItemProps = { | type ItemProps = { | ||||
| data: ApiBasedExtension | data: ApiBasedExtension | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| { | { | ||||
| showDeleteConfirm && ( | |||||
| <ConfirmCommon | |||||
| type='danger' | |||||
| showDeleteConfirm | |||||
| && <Confirm | |||||
| isShow={showDeleteConfirm} | isShow={showDeleteConfirm} | ||||
| onCancel={() => setShowDeleteConfirm(false)} | onCancel={() => setShowDeleteConfirm(false)} | ||||
| title={`${t('common.operation.delete')} “${data.name}”?`} | title={`${t('common.operation.delete')} “${data.name}”?`} | ||||
| onConfirm={handleDeleteApiBasedExtension} | onConfirm={handleDeleteApiBasedExtension} | ||||
| confirmWrapperClassName='!z-30' | |||||
| confirmText={t('common.operation.delete') || ''} | confirmText={t('common.operation.delete') || ''} | ||||
| confirmBtnClassName='!bg-[#D92D20]' | |||||
| /> | /> | ||||
| ) | |||||
| } | } | ||||
| </div> | </div> | ||||
| ) | ) |
| PortalToFollowElemContent, | PortalToFollowElemContent, | ||||
| } from '@/app/components/base/portal-to-follow-elem' | } from '@/app/components/base/portal-to-follow-elem' | ||||
| import { useToastContext } from '@/app/components/base/toast' | import { useToastContext } from '@/app/components/base/toast' | ||||
| import ConfirmCommon from '@/app/components/base/confirm/common' | |||||
| import Confirm from '@/app/components/base/confirm' | |||||
| import { useAppContext } from '@/context/app-context' | import { useAppContext } from '@/context/app-context' | ||||
| type ModelModalProps = { | type ModelModalProps = { | ||||
| </div> | </div> | ||||
| { | { | ||||
| showConfirm && ( | showConfirm && ( | ||||
| <ConfirmCommon | |||||
| <Confirm | |||||
| title={t('common.modelProvider.confirmDelete')} | title={t('common.modelProvider.confirmDelete')} | ||||
| isShow={showConfirm} | isShow={showConfirm} | ||||
| onCancel={() => setShowConfirm(false)} | onCancel={() => setShowConfirm(false)} | ||||
| onConfirm={handleRemove} | onConfirm={handleRemove} | ||||
| confirmWrapperClassName='z-[70]' | |||||
| /> | /> | ||||
| ) | ) | ||||
| } | } |
| PortalToFollowElemContent, | PortalToFollowElemContent, | ||||
| } from '@/app/components/base/portal-to-follow-elem' | } from '@/app/components/base/portal-to-follow-elem' | ||||
| import { useToastContext } from '@/app/components/base/toast' | import { useToastContext } from '@/app/components/base/toast' | ||||
| import ConfirmCommon from '@/app/components/base/confirm/common' | |||||
| import Confirm from '@/app/components/base/confirm' | |||||
| type ModelModalProps = { | type ModelModalProps = { | ||||
| provider: ModelProvider | provider: ModelProvider | ||||
| </div> | </div> | ||||
| { | { | ||||
| showConfirm && ( | showConfirm && ( | ||||
| <ConfirmCommon | |||||
| <Confirm | |||||
| title={t('common.modelProvider.confirmDelete')} | title={t('common.modelProvider.confirmDelete')} | ||||
| isShow={showConfirm} | isShow={showConfirm} | ||||
| onCancel={() => setShowConfirm(false)} | onCancel={() => setShowConfirm(false)} | ||||
| onConfirm={handleRemove} | onConfirm={handleRemove} | ||||
| confirmWrapperClassName='z-[70]' | |||||
| /> | /> | ||||
| ) | ) | ||||
| } | } |
| title={t('tools.createTool.deleteToolConfirmTitle')} | title={t('tools.createTool.deleteToolConfirmTitle')} | ||||
| content={t('tools.createTool.deleteToolConfirmContent')} | content={t('tools.createTool.deleteToolConfirmContent')} | ||||
| isShow={showConfirmDelete} | isShow={showConfirmDelete} | ||||
| onClose={() => setShowConfirmDelete(false)} | |||||
| onConfirm={handleConfirmDelete} | onConfirm={handleConfirmDelete} | ||||
| onCancel={() => setShowConfirmDelete(false)} | onCancel={() => setShowConfirmDelete(false)} | ||||
| /> | /> |
| return ( | return ( | ||||
| <div className='flex items-center h-[18px] text-xs text-gray-500'> | <div className='flex items-center h-[18px] text-xs text-gray-500'> | ||||
| <ClockRefresh className='mr-1 w-3 h-3 text-gray-500' /> | <ClockRefresh className='mr-1 w-3 h-3 text-gray-500' /> | ||||
| {t('workflow.common.latestPublished')} | |||||
| {t('workflow.common.latestPublished')}<span> </span> | |||||
| {formatTimeFromNow(publishedAt)} | {formatTimeFromNow(publishedAt)} | ||||
| </div> | </div> | ||||
| ) | ) |
| import type { Features as FeaturesData } from '@/app/components/base/features/types' | import type { Features as FeaturesData } from '@/app/components/base/features/types' | ||||
| import { useFeaturesStore } from '@/app/components/base/features/hooks' | import { useFeaturesStore } from '@/app/components/base/features/hooks' | ||||
| import { useEventEmitterContextContext } from '@/context/event-emitter' | import { useEventEmitterContextContext } from '@/context/event-emitter' | ||||
| import Confirm from '@/app/components/base/confirm/common' | |||||
| import Confirm from '@/app/components/base/confirm' | |||||
| const nodeTypes = { | const nodeTypes = { | ||||
| [CUSTOM_NODE]: CustomNode, | [CUSTOM_NODE]: CustomNode, | ||||
| onCancel={() => setShowConfirm(undefined)} | onCancel={() => setShowConfirm(undefined)} | ||||
| onConfirm={showConfirm.onConfirm} | onConfirm={showConfirm.onConfirm} | ||||
| title={showConfirm.title} | title={showConfirm.title} | ||||
| desc={showConfirm.desc} | |||||
| confirmWrapperClassName='!z-[11]' | |||||
| content={showConfirm.desc} | |||||
| /> | /> | ||||
| ) | ) | ||||
| } | } |
| content={t(`${i18nPrefix}.content`)} | content={t(`${i18nPrefix}.content`)} | ||||
| onConfirm={onConfirm} | onConfirm={onConfirm} | ||||
| onCancel={onCancel} | onCancel={onCancel} | ||||
| onClose={onCancel} | |||||
| /> | /> | ||||
| ) | ) | ||||
| } | } |
| fetchDataSourceNotionBinding, | fetchDataSourceNotionBinding, | ||||
| fetchFreeQuotaVerify, | fetchFreeQuotaVerify, | ||||
| } from '@/service/common' | } from '@/service/common' | ||||
| import type { ConfirmCommonProps } from '@/app/components/base/confirm/common' | |||||
| import Confirm from '@/app/components/base/confirm/common' | |||||
| import type { IConfirm } from '@/app/components/base/confirm' | |||||
| import Confirm from '@/app/components/base/confirm' | |||||
| export type ConfirmType = Pick<ConfirmCommonProps, 'type' | 'title' | 'desc'> | |||||
| export type ConfirmType = Pick<IConfirm, 'type' | 'title' | 'content'> | |||||
| export const useAnthropicCheckPay = () => { | export const useAnthropicCheckPay = () => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (providerName === 'anthropic' && (paymentResult === 'succeeded' || paymentResult === 'cancelled')) { | if (providerName === 'anthropic' && (paymentResult === 'succeeded' || paymentResult === 'cancelled')) { | ||||
| setConfirm({ | setConfirm({ | ||||
| type: paymentResult === 'succeeded' ? 'success' : 'danger', | |||||
| type: paymentResult === 'succeeded' ? 'info' : 'warning', | |||||
| title: paymentResult === 'succeeded' ? t('common.actionMsg.paySucceeded') : t('common.actionMsg.payCancelled'), | title: paymentResult === 'succeeded' ? t('common.actionMsg.paySucceeded') : t('common.actionMsg.payCancelled'), | ||||
| }) | }) | ||||
| } | } | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (paymentType === 'billing' && (paymentResult === 'succeeded' || paymentResult === 'cancelled')) { | if (paymentType === 'billing' && (paymentResult === 'succeeded' || paymentResult === 'cancelled')) { | ||||
| setConfirm({ | setConfirm({ | ||||
| type: paymentResult === 'succeeded' ? 'success' : 'danger', | |||||
| type: paymentResult === 'succeeded' ? 'info' : 'warning', | |||||
| title: paymentResult === 'succeeded' ? t('common.actionMsg.paySucceeded') : t('common.actionMsg.payCancelled'), | title: paymentResult === 'succeeded' ? t('common.actionMsg.paySucceeded') : t('common.actionMsg.payCancelled'), | ||||
| }) | }) | ||||
| } | } | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (error) | if (error) | ||||
| router.replace('/', { forceOptimisticNavigation: false }) | |||||
| router.replace('/') | |||||
| }, [error, router]) | }, [error, router]) | ||||
| useEffect(() => { | useEffect(() => { | ||||
| return (data && provider) | return (data && provider) | ||||
| ? { | ? { | ||||
| type: data.flag ? 'success' : 'danger', | |||||
| type: data.flag ? 'info' : 'warning', | |||||
| title: data.flag ? QUOTA_RECEIVE_STATUS[provider as string].success[locale] : QUOTA_RECEIVE_STATUS[provider].fail[locale], | title: data.flag ? QUOTA_RECEIVE_STATUS[provider as string].success[locale] : QUOTA_RECEIVE_STATUS[provider].fail[locale], | ||||
| desc: !data.flag ? data.reason : undefined, | desc: !data.flag ? data.reason : undefined, | ||||
| } | } | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (data) | if (data) | ||||
| router.replace('/', { forceOptimisticNavigation: false }) | |||||
| router.replace('/') | |||||
| }, [data, router]) | }, [data, router]) | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (type === 'notion') { | if (type === 'notion') { | ||||
| if (notionError) { | if (notionError) { | ||||
| setConfirm({ | setConfirm({ | ||||
| type: 'danger', | |||||
| type: 'warning', | |||||
| title: notionError, | title: notionError, | ||||
| }) | }) | ||||
| } | } | ||||
| const handleCancelShowPayStatusModal = useCallback(() => { | const handleCancelShowPayStatusModal = useCallback(() => { | ||||
| setShowPayStatusModal(false) | setShowPayStatusModal(false) | ||||
| router.replace('/', { forceOptimisticNavigation: false }) | |||||
| router.replace('/') | |||||
| }, [router]) | }, [router]) | ||||
| const confirmInfo = anthropicConfirmInfo || freeQuotaConfirmInfo || notionConfirmInfo || billingConfirmInfo | const confirmInfo = anthropicConfirmInfo || freeQuotaConfirmInfo || notionConfirmInfo || billingConfirmInfo | ||||
| isShow | isShow | ||||
| onCancel={handleCancelShowPayStatusModal} | onCancel={handleCancelShowPayStatusModal} | ||||
| onConfirm={handleCancelShowPayStatusModal} | onConfirm={handleCancelShowPayStatusModal} | ||||
| type={confirmInfo.type} | |||||
| showCancel={false} | |||||
| type={confirmInfo.type === 'info' ? 'info' : 'warning' } | |||||
| title={confirmInfo.title} | title={confirmInfo.title} | ||||
| desc={confirmInfo.desc} | |||||
| showOperateCancel={false} | |||||
| confirmText={(confirmInfo.type === 'danger' && t('common.operation.ok')) || ''} | |||||
| content={(confirmInfo as { desc: string }).desc || ''} | |||||
| confirmText={(confirmInfo.type === 'info' && t('common.operation.ok')) || ''} | |||||
| /> | /> | ||||
| ) | ) | ||||
| } | } |
| getFreeTokens: 'Get free Tokens', | getFreeTokens: 'Get free Tokens', | ||||
| priorityUsing: 'Prioritize using', | priorityUsing: 'Prioritize using', | ||||
| deprecated: 'Deprecated', | deprecated: 'Deprecated', | ||||
| confirmDelete: 'confirm deletion?', | |||||
| confirmDelete: 'Confirm deletion?', | |||||
| quotaTip: 'Remaining available free tokens', | quotaTip: 'Remaining available free tokens', | ||||
| loadPresets: 'Load Presents', | loadPresets: 'Load Presents', | ||||
| parameters: 'PARAMETERS', | parameters: 'PARAMETERS', |