feat: new result

feat/enchance-prompt-and-code-fe
Joel 7 months ago
parent 424a563055
commit 945a424fa8

@ -21,14 +21,10 @@ import Button from '@/app/components/base/button'
import Textarea from '@/app/components/base/textarea' import Textarea from '@/app/components/base/textarea'
import Toast from '@/app/components/base/toast' import Toast from '@/app/components/base/toast'
import { generateRule } from '@/service/debug' import { generateRule } from '@/service/debug'
import ConfigPrompt from '@/app/components/app/configuration/config-prompt'
import type { CompletionParams, Model } from '@/types/app' import type { CompletionParams, Model } from '@/types/app'
import { AppType } from '@/types/app' import type { AppType } from '@/types/app'
import ConfigVar from '@/app/components/app/configuration/config-var'
import GroupName from '@/app/components/app/configuration/base/group-name'
import Loading from '@/app/components/base/loading' import Loading from '@/app/components/base/loading'
import Confirm from '@/app/components/base/confirm' import Confirm from '@/app/components/base/confirm'
import { LoveMessage } from '@/app/components/base/icons/src/vender/features'
// type // type
import type { AutomaticRes } from '@/service/debug' import type { AutomaticRes } from '@/service/debug'
@ -44,6 +40,7 @@ import type { Node, NodeOutPutVar } from '@/app/components/workflow/types'
import type { GeneratorType } from './types' import type { GeneratorType } from './types'
import { ArrowDownRoundFill } from '@/app/components/base/icons/src/vender/solid/general' import { ArrowDownRoundFill } from '@/app/components/base/icons/src/vender/solid/general'
import Link from 'next/link' import Link from 'next/link'
import Result from './result'
const i18nPrefix = 'appDebug.generate' const i18nPrefix = 'appDebug.generate'
export type IGetAutomaticResProps = { export type IGetAutomaticResProps = {
@ -54,6 +51,8 @@ export type IGetAutomaticResProps = {
nodesOutputVars?: NodeOutPutVar[] nodesOutputVars?: NodeOutPutVar[]
availableNodes?: Node[] availableNodes?: Node[]
generatorType: GeneratorType generatorType: GeneratorType
flowId: string
nodeId?: string
isBasicMode?: boolean isBasicMode?: boolean
} }
@ -80,6 +79,8 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
nodesOutputVars, nodesOutputVars,
availableNodes, availableNodes,
generatorType, generatorType,
flowId,
nodeId,
isBasicMode, isBasicMode,
onFinished, onFinished,
}) => { }) => {
@ -189,7 +190,7 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
const renderNoData = ( const renderNoData = (
<div className='flex h-full w-0 grow flex-col items-center justify-center space-y-3 px-8'> <div className='flex h-full w-0 grow flex-col items-center justify-center space-y-3 px-8'>
<Generator className='h-14 w-14 text-text-tertiary' /> <Generator className='size-8 text-text-quaternary' />
<div className='text-center text-[13px] font-normal leading-5 text-text-tertiary'> <div className='text-center text-[13px] font-normal leading-5 text-text-tertiary'>
<div>{t('appDebug.generate.newNoDataLine1')}</div> <div>{t('appDebug.generate.newNoDataLine1')}</div>
<Link className='text-text-accent' href='//todo' target='_blank'>{t('appDebug.generate.newNoDataLine2')}</Link> <Link className='text-text-accent' href='//todo' target='_blank'>{t('appDebug.generate.newNoDataLine2')}</Link>
@ -241,7 +242,10 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
} }
} }
const [showConfirmOverwrite, setShowConfirmOverwrite] = React.useState(false) const [isShowConfirmOverwrite, {
setTrue: showConfirmOverwrite,
setFalse: hideShowConfirmOverwrite,
}] = useBoolean(false)
const isShowAutoPromptResPlaceholder = () => { const isShowAutoPromptResPlaceholder = () => {
return !isLoading && !res return !isLoading && !res
@ -252,7 +256,6 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
isShow={isShow} isShow={isShow}
onClose={onClose} onClose={onClose}
className='min-w-[1140px] !p-0' className='min-w-[1140px] !p-0'
closable
> >
<div className='flex h-[680px] flex-wrap'> <div className='flex h-[680px] flex-wrap'>
<div className='h-full w-[570px] shrink-0 overflow-y-auto border-r border-divider-regular p-6'> <div className='h-full w-[570px] shrink-0 overflow-y-auto border-r border-divider-regular p-6'>
@ -341,73 +344,28 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
</div> </div>
</div> </div>
{(!isLoading && res) && ( {/* {(!isLoading && res) && ( */}
{
<div className='h-full w-0 grow p-6 pb-0'> <div className='h-full w-0 grow p-6 pb-0'>
<div className='mb-3 shrink-0 text-base font-semibold leading-[160%] text-text-secondary'>{t('appDebug.generate.resTitle')}</div> <Result
<div className={cn('max-h-[555px] overflow-y-auto', isBasicMode && 'pb-2')}> storageKey={`${flowId}${isBasicMode ? '' : `-${nodeId}`}`}
<ConfigPrompt onApply={showConfirmOverwrite}
mode={mode} generatorType={generatorType}
promptTemplate={res?.prompt || ''}
promptVariables={[]}
readonly
noTitle={!isBasicMode}
gradientBorder
editorHeight={!isBasicMode ? 524 : 0}
noResize={!isBasicMode}
/>
{isBasicMode && (
<>
{(res?.variables?.length && res?.variables?.length > 0)
? (
<ConfigVar
promptVariables={res?.variables.map(key => ({ key, name: key, type: 'string', required: true })) || []}
readonly
/> />
)
: ''}
{(mode !== AppType.completion && res?.opening_statement) && (
<div className='mt-7'>
<GroupName name={t('appDebug.feature.groupChat.title')} />
<div
className='mb-1 rounded-xl border-l-[0.5px] border-t-[0.5px] border-effects-highlight bg-background-section-burn p-3'
>
<div className='mb-2 flex items-center gap-2'>
<div className='shrink-0 rounded-lg border-[0.5px] border-divider-subtle bg-util-colors-blue-light-blue-light-500 p-1 shadow-xs'>
<LoveMessage className='h-4 w-4 text-text-primary-on-surface' />
</div>
<div className='system-sm-semibold flex grow items-center text-text-secondary'>
{t('appDebug.feature.conversationOpener.title')}
</div>
</div> </div>
<div className='system-xs-regular min-h-8 text-text-tertiary'>{res.opening_statement}</div> }
</div>
</div>
)}
</>
)}
</div>
<div className='flex justify-end bg-background-default py-4'>
<Button onClick={onClose}>{t('common.operation.cancel')}</Button>
<Button variant='primary' className='ml-2' onClick={() => {
setShowConfirmOverwrite(true)
}}>{t('appDebug.generate.apply')}</Button>
</div>
</div>
)}
{isLoading && renderLoading} {isLoading && renderLoading}
{isShowAutoPromptResPlaceholder() && renderNoData} {isShowAutoPromptResPlaceholder() && !renderNoData}
{showConfirmOverwrite && ( {isShowConfirmOverwrite && (
<Confirm <Confirm
title={t('appDebug.generate.overwriteTitle')} title={t('appDebug.generate.overwriteTitle')}
content={t('appDebug.generate.overwriteMessage')} content={t('appDebug.generate.overwriteMessage')}
isShow={showConfirmOverwrite} isShow
onConfirm={() => { onConfirm={() => {
setShowConfirmOverwrite(false) hideShowConfirmOverwrite()
onFinished(res!) onFinished(res!)
}} }}
onCancel={() => setShowConfirmOverwrite(false)} onCancel={hideShowConfirmOverwrite}
/> />
)} )}
</div> </div>

@ -0,0 +1,34 @@
import { RiCloseLine, RiInformation2Fill } from '@remixicon/react'
import { useBoolean } from 'ahooks'
import React from 'react'
import cn from '@/utils/classnames'
type Props = {
className?: string
}
const PromptToast = ({
className,
}: Props) => {
const [isHide, {
setTrue: hide,
}] = useBoolean(false)
if(isHide)
return
return (
<div className={cn('relative flex h-10 items-center p-2 ', className)}>
{/* Background Effect */}
<div className="pointer-events-none absolute inset-0 rounded-lg bg-[linear-gradient(92deg,rgba(11,165,236,0.25)_0%,rgba(255,255,255,0.00)_100%)] opacity-40 shadow-md"></div>
<div className='relative flex h-full w-full items-center justify-between'>
<div className="flex h-full items-center gap-1">
<RiInformation2Fill className="size-4 text-text-accent" />
<p className="text-sm text-gray-700">This is the modified prompt with added context.</p>
</div>
<div className='cursor-pointer p-0.5' onClick={hide}>
<RiCloseLine className='size-5 text-text-tertiary' />
</div>
</div>
</div>
)
}
export default PromptToast

@ -0,0 +1,47 @@
'use client'
import type { FC } from 'react'
import React, { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import { GeneratorType } from './types'
import PromptToast from './prompt-toast'
import Button from '@/app/components/base/button'
type Props = {
storageKey: string
onApply: (result: string) => void
generatorType: GeneratorType
}
const Result: FC<Props> = ({
storageKey,
onApply,
generatorType,
}) => {
const { t } = useTranslation()
const isGeneratorPrompt = generatorType === GeneratorType.prompt
const handleApply = useCallback(() => {
onApply('xxx')
}, [onApply])
// todo current version and version list
const current = 'xxxx'
return (
<div>
<div className='mb-3 flex items-center justify-between'>
<div className='shrink-0 text-base font-semibold leading-[160%] text-text-secondary'>{t('appDebug.generate.resTitle')}</div>
<div className='flex space-x-2'>
<Button variant='primary' onClick={handleApply}>
{t('appDebug.generate.apply')}
</Button>
</div>
</div>
{
isGeneratorPrompt && (
<PromptToast className='mt-4' />
)
}
<div className='mt-3'>{current}</div>
</div>
)
}
export default React.memo(Result)
Loading…
Cancel
Save