Merge branch 'fix/app-detail-panel-merge-issue' into dev/plugin-deploy

This commit is contained in:
Yi
2025-02-10 12:01:57 +08:00
199 changed files with 3636 additions and 2136 deletions

View File

@ -45,13 +45,13 @@ const NodeControl: FC<NodeControlProps> = ({
`}
>
<div
className='flex items-center px-0.5 h-6 bg-white rounded-lg border-[0.5px] border-gray-100 shadow-xs text-gray-500'
className='flex items-center px-0.5 h-6 bg-components-actionbar-bg rounded-lg border-[0.5px] border-components-actionbar-border backdrop-blur-[5px] shadow-md text-text-tertiary'
onClick={e => e.stopPropagation()}
>
{
canRunBySingle(data.type) && (
<div
className='flex items-center justify-center w-5 h-5 rounded-md cursor-pointer hover:bg-black/5'
className='flex items-center justify-center w-5 h-5 rounded-md cursor-pointer hover:bg-state-base-hover'
onClick={() => {
handleNodeDataUpdate({
id,

View File

@ -54,12 +54,12 @@ const PanelOperator = ({
<div
className={`
flex items-center justify-center w-6 h-6 rounded-md cursor-pointer
hover:bg-black/5
${open && 'bg-black/5'}
hover:bg-state-base-hover
${open && 'bg-state-base-hover'}
${triggerClassName}
`}
>
<RiMoreFill className={`w-4 h-4 ${inNode ? 'text-gray-500' : 'text-gray-700'}`} />
<RiMoreFill className={'w-4 h-4 text-text-tertiary'} />
</div>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent className='z-[11]'>

View File

@ -33,10 +33,8 @@ export const TitleInput = memo(({
value={localValue}
onChange={e => setLocalValue(e.target.value)}
className={`
grow mr-2 px-1 h-6 text-base text-gray-900 font-semibold rounded-lg border border-transparent appearance-none outline-none
hover:bg-gray-50
focus:border-gray-300 focus:shadow-xs focus:bg-white caret-[#295EFF]
min-w-0
grow mr-2 px-1 h-7 text-text-primary system-xl-semibold rounded-md border border-transparent appearance-none outline-none
focus:shadow-xs min-w-0
`}
placeholder={t('workflow.common.addTitle') || ''}
onBlur={handleBlur}
@ -66,8 +64,8 @@ export const DescriptionInput = memo(({
<div
className={`
group flex px-2 py-[5px] max-h-[60px] rounded-lg overflow-y-auto
border border-transparent hover:bg-gray-50 leading-0
${focus && '!border-gray-300 shadow-xs !bg-gray-50'}
leading-0 bg-components-panel-bg
${focus && '!shadow-xs'}
`}
>
<Textarea

View File

@ -588,7 +588,9 @@ export const getVarType = ({
else {
(valueSelector as ValueSelector).slice(1).forEach((key, i) => {
const isLast = i === valueSelector.length - 2
curr = curr?.find((v: any) => v.variable === key)
if (Array.isArray(curr))
curr = curr?.find((v: any) => v.variable === key)
if (isLast) {
type = curr?.type
}

View File

@ -272,7 +272,7 @@ const VarReferencePicker: FC<Props> = ({
<AddButton onClick={() => { }}></AddButton>
</div>
)
: (<div ref={!isSupportConstantValue ? triggerRef : null} className={cn((open || isFocus) ? 'border-gray-300' : 'border-gray-100', 'relative group/wrap flex items-center w-full h-8', !isSupportConstantValue && 'p-1 rounded-lg bg-gray-100 border', isInTable && 'bg-transparent border-none', readonly && 'bg-components-input-bg-disabled')}>
: (<div ref={!isSupportConstantValue ? triggerRef : null} className={cn((open || isFocus) ? 'border-gray-300' : 'border-gray-100', 'relative group/wrap flex items-center w-full h-8', !isSupportConstantValue && 'p-1 rounded-lg bg-components-input-bg-normal', isInTable && 'bg-transparent border-none', readonly && 'bg-components-input-bg-disabled')}>
{isSupportConstantValue
? <div onClick={(e) => {
e.stopPropagation()

View File

@ -107,7 +107,7 @@ const BaseNode: FC<BaseNodeProps> = ({
'group relative pb-1 shadow-xs',
'border border-transparent rounded-[15px]',
data.type !== BlockEnum.Iteration && 'w-[240px] bg-workflow-block-bg',
data.type === BlockEnum.Iteration && 'flex flex-col w-full h-full bg-[#fcfdff]/80',
data.type === BlockEnum.Iteration && 'flex flex-col w-full h-full bg-workflow-block-bg-transparent border-workflow-block-border',
!data._runningStatus && 'hover:shadow-lg',
showRunningBorder && '!border-state-accent-solid',
showSuccessBorder && '!border-state-success-solid',
@ -169,7 +169,7 @@ const BaseNode: FC<BaseNodeProps> = ({
}
<div className={cn(
'flex items-center px-3 pt-3 pb-2 rounded-t-2xl',
data.type === BlockEnum.Iteration && 'bg-[rgba(250,252,255,0.9)]',
data.type === BlockEnum.Iteration && 'bg-transparent',
)}>
<BlockIcon
className='shrink-0 mr-2'

View File

@ -1,5 +1,5 @@
import type { StrategyDetail, StrategyPluginDetail } from '@/app/components/plugins/types'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '../../constants'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks'
import type { NodeDefault } from '../../types'
import type { AgentNodeType } from './types'
import { FormTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'

View File

@ -1,7 +1,7 @@
import { BlockEnum } from '../../types'
import type { NodeDefault } from '../../types'
import type { AnswerNodeType } from './types'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks'
const nodeDefault: NodeDefault<AnswerNodeType> = {
defaultValue: {

View File

@ -1,7 +1,7 @@
import { BlockEnum } from '../../types'
import type { NodeDefault } from '../../types'
import { type AssignerNodeType, WriteMode } from './types'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks'
const i18nPrefix = 'workflow.errorMsg'
const nodeDefault: NodeDefault<AssignerNodeType> = {

View File

@ -1,7 +1,7 @@
import { BlockEnum } from '../../types'
import type { NodeDefault } from '../../types'
import { CodeLanguage, type CodeNodeType } from './types'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks'
const i18nPrefix = 'workflow.errorMsg'

View File

@ -1,7 +1,7 @@
import { BlockEnum } from '../../types'
import type { NodeDefault } from '../../types'
import type { DocExtractorNodeType } from './types'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks'
const i18nPrefix = 'workflow.errorMsg'
const nodeDefault: NodeDefault<DocExtractorNodeType> = {

View File

@ -1,7 +1,7 @@
import { BlockEnum } from '../../types'
import type { NodeDefault } from '../../types'
import type { EndNodeType } from './types'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks'
const nodeDefault: NodeDefault<EndNodeType> = {
defaultValue: {

View File

@ -5,7 +5,7 @@ import type { BodyPayload, HttpNodeType } from './types'
import {
ALL_CHAT_AVAILABLE_BLOCKS,
ALL_COMPLETION_AVAILABLE_BLOCKS,
} from '@/app/components/workflow/constants'
} from '@/app/components/workflow/blocks'
const nodeDefault: NodeDefault<HttpNodeType> = {
defaultValue: {

View File

@ -1,7 +1,8 @@
import { BlockEnum, type NodeDefault } from '../../types'
import { type IfElseNodeType, LogicalOperator } from './types'
import { isEmptyRelatedOperator } from './utils'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
import { TransferMethod } from '@/types/app'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks'
const i18nPrefix = 'workflow.errorMsg'
const nodeDefault: NodeDefault<IfElseNodeType> = {

View File

@ -1,6 +1,6 @@
import type { NodeDefault } from '../../types'
import type { IterationStartNodeType } from './types'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks'
const nodeDefault: NodeDefault<IterationStartNodeType> = {
defaultValue: {},

View File

@ -9,7 +9,7 @@ const IterationStartNode = ({ id, data }: NodeProps) => {
const { t } = useTranslation()
return (
<div className='group flex nodrag items-center justify-center w-11 h-11 mt-1 rounded-2xl border border-workflow-block-border bg-white'>
<div className='group flex nodrag items-center justify-center w-11 h-11 mt-1 rounded-2xl border border-workflow-block-border bg-workflow-block-bg shadow-xs'>
<Tooltip popupContent={t('workflow.blocks.iteration-start')} asChild={false}>
<div className='flex items-center justify-center w-6 h-6 rounded-full border-[0.5px] border-components-panel-border-subtle bg-util-colors-blue-brand-blue-brand-500'>
<RiHome5Fill className='w-3 h-3 text-text-primary-on-surface' />

View File

@ -49,9 +49,9 @@ const AddBlock = ({
const renderTriggerElement = useCallback((open: boolean) => {
return (
<div className={cn(
'relative inline-flex items-center px-3 h-8 rounded-lg border-[0.5px] border-gray-50 bg-white shadow-xs cursor-pointer hover:bg-gray-200 text-[13px] font-medium text-gray-700',
`${nodesReadOnly && '!cursor-not-allowed opacity-50'}`,
open && '!bg-gray-50',
'relative inline-flex items-center px-3 h-8 rounded-lg border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg shadow-xs cursor-pointer hover:bg-components-button-secondary-bg-hover system-sm-medium text-components-button-secondary-text backdrop-blur-[5px]',
`${nodesReadOnly && '!cursor-not-allowed bg-components-button-secondary-bg-disabled'}`,
open && 'bg-components-button-secondary-bg-hover',
)}>
<RiAddLine className='mr-1 w-4 h-4' />
{t('workflow.common.addBlock')}

View File

@ -4,7 +4,7 @@ import type { IterationNodeType } from './types'
import {
ALL_CHAT_AVAILABLE_BLOCKS,
ALL_COMPLETION_AVAILABLE_BLOCKS,
} from '@/app/components/workflow/constants'
} from '@/app/components/workflow/blocks'
const i18nPrefix = 'workflow'
const nodeDefault: NodeDefault<IterationNodeType> = {

View File

@ -43,14 +43,14 @@ const Node: FC<NodeProps<IterationNodeType>> = ({
return (
<div className={cn(
'relative min-w-[240px] min-h-[90px] w-full h-full rounded-2xl bg-[#F0F2F7]/90',
'relative min-w-[240px] min-h-[90px] w-full h-full rounded-2xl',
)}>
<Background
id={`iteration-background-${id}`}
className='rounded-2xl !z-0'
gap={[14 / zoom, 14 / zoom]}
size={2 / zoom}
color='#E4E5E7'
color='var(--color-workflow-canvas-workflow-dot-color)'
/>
{
data._isCandidate && (

View File

@ -74,7 +74,7 @@ const Panel: FC<NodePanelProps<IterationNodeType>> = ({
<Field
title={t(`${i18nPrefix}.input`)}
operations={(
<div className='flex items-center h-[18px] px-1 border border-black/8 rounded-[5px] text-xs font-medium text-gray-500 capitalize'>Array</div>
<div className='flex items-center h-[18px] px-1 border border-divider-deep rounded-[5px] system-2xs-medium-uppercase text-text-tertiary capitalize'>Array</div>
)}
>
<VarReferencePicker
@ -92,7 +92,7 @@ const Panel: FC<NodePanelProps<IterationNodeType>> = ({
<Field
title={t(`${i18nPrefix}.output`)}
operations={(
<div className='flex items-center h-[18px] px-1 border border-black/8 rounded-[5px] text-xs font-medium text-gray-500 capitalize'>Array</div>
<div className='flex items-center h-[18px] px-1 border border-divider-deep rounded-[5px] system-2xs-medium-uppercase text-text-tertiary capitalize'>Array</div>
)}
>
<VarReferencePicker
@ -132,8 +132,7 @@ const Panel: FC<NodePanelProps<IterationNodeType>> = ({
<div className='px-4 py-2'>
<Field title={t(`${i18nPrefix}.errorResponseMethod`)} >
<Select items={responseMethod} defaultValue={inputs.error_handle_mode} onSelect={changeErrorResponseMode} allowSearch={false}>
</Select>
<Select items={responseMethod} defaultValue={inputs.error_handle_mode} onSelect={changeErrorResponseMode} allowSearch={false} />
</Field>
</div>

View File

@ -18,11 +18,12 @@ import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import Badge from '@/app/components/base/badge'
import { useKnowledge } from '@/hooks/use-knowledge'
interface Props {
type Props = {
payload: DataSet
onRemove: () => void
onChange: (dataSet: DataSet) => void
readonly?: boolean
editable?: boolean
}
const DatasetItem: FC<Props> = ({
@ -30,6 +31,7 @@ const DatasetItem: FC<Props> = ({
onRemove,
onChange,
readonly,
editable = true,
}) => {
const media = useBreakpoints()
const { t } = useTranslation()
@ -75,21 +77,23 @@ const DatasetItem: FC<Props> = ({
</div>
{!readonly && (
<div className='hidden group-hover/dataset-item:flex shrink-0 ml-2 items-center space-x-1'>
<ActionButton
onClick={(e) => {
e.stopPropagation()
showSettingsModal()
}}
>
<RiEditLine className='w-4 h-4 flex-shrink-0 text-text-tertiary' />
</ActionButton>
{
editable && <ActionButton
onClick={(e) => {
e.stopPropagation()
showSettingsModal()
}}
>
<RiEditLine className='w-4 h-4 shrink-0 text-text-tertiary' />
</ActionButton>
}
<ActionButton
onClick={handleRemove}
state={ActionButtonState.Destructive}
onMouseEnter={() => setIsDeleteHovered(true)}
onMouseLeave={() => setIsDeleteHovered(false)}
>
<RiDeleteBinLine className={`w-4 h-4 flex-shrink-0 ${isDeleteHovered ? 'text-text-destructive' : 'text-text-tertiary'}`} />
<RiDeleteBinLine className={`w-4 h-4 shrink-0 ${isDeleteHovered ? 'text-text-destructive' : 'text-text-tertiary'}`} />
</ActionButton>
</div>
)}
@ -102,7 +106,7 @@ const DatasetItem: FC<Props> = ({
{
payload.provider === 'external' && <Badge
className='group-hover/dataset-item:hidden shrink-0'
text={t('dataset.externalTag')}
text={t('dataset.externalTag') as string}
/>
}

View File

@ -1,10 +1,13 @@
'use client'
import type { FC } from 'react'
import React, { useCallback } from 'react'
import React, { useCallback, useMemo } from 'react'
import produce from 'immer'
import { useTranslation } from 'react-i18next'
import Item from './dataset-item'
import type { DataSet } from '@/models/datasets'
import { useSelector as useAppContextSelector } from '@/context/app-context'
import { hasEditPermissionForDataset } from '@/utils/permission'
type Props = {
list: DataSet[]
onChange: (list: DataSet[]) => void
@ -17,6 +20,7 @@ const DatasetList: FC<Props> = ({
readonly,
}) => {
const { t } = useTranslation()
const userProfile = useAppContextSelector(s => s.userProfile)
const handleRemove = useCallback((index: number) => {
return () => {
@ -35,10 +39,25 @@ const DatasetList: FC<Props> = ({
onChange(newList)
}
}, [list, onChange])
const formattedList = useMemo(() => {
return list.map((item) => {
const datasetConfig = {
createdBy: item.created_by,
partialMemberList: item.partial_member_list || [],
permission: item.permission,
}
return {
...item,
editable: hasEditPermissionForDataset(userProfile?.id || '', datasetConfig),
}
})
}, [list, userProfile?.id])
return (
<div className='space-y-1'>
{list.length
? list.map((item, index) => {
{formattedList.length
? formattedList.map((item, index) => {
return (
<Item
key={index}
@ -46,6 +65,7 @@ const DatasetList: FC<Props> = ({
onRemove={handleRemove(index)}
onChange={handleChange(index)}
readonly={readonly}
editable={item.editable}
/>
)
})

View File

@ -2,7 +2,7 @@ import { BlockEnum } from '../../types'
import type { NodeDefault } from '../../types'
import type { KnowledgeRetrievalNodeType } from './types'
import { checkoutRerankModelConfigedInRetrievalSettings } from './utils'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks'
import { DATASET_DEFAULT } from '@/config'
import { RETRIEVE_TYPE } from '@/types/app'
const i18nPrefix = 'workflow'

View File

@ -2,7 +2,7 @@ import { BlockEnum, VarType } from '../../types'
import type { NodeDefault } from '../../types'
import { comparisonOperatorNotRequireValue } from '../if-else/utils'
import { type ListFilterNodeType, OrderBy } from './types'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks'
const i18nPrefix = 'workflow.errorMsg'
const nodeDefault: NodeDefault<ListFilterNodeType> = {

View File

@ -1,7 +1,7 @@
import { BlockEnum, EditionType } from '../../types'
import { type NodeDefault, type PromptItem, PromptRole } from '../../types'
import type { LLMNodeType } from './types'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks'
const i18nPrefix = 'workflow.errorMsg'

View File

@ -1,7 +1,7 @@
import { BlockEnum } from '../../types'
import type { NodeDefault } from '../../types'
import { type ParameterExtractorNodeType, ReasoningModeType } from './types'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks'
const i18nPrefix = 'workflow'
const nodeDefault: NodeDefault<ParameterExtractorNodeType> = {

View File

@ -1,7 +1,7 @@
import type { NodeDefault } from '../../types'
import { BlockEnum } from '../../types'
import type { QuestionClassifierNodeType } from './types'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks'
const i18nPrefix = 'workflow'

View File

@ -1,6 +1,6 @@
import type { NodeDefault } from '../../types'
import type { StartNodeType } from './types'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks'
const nodeDefault: NodeDefault<StartNodeType> = {
defaultValue: {

View File

@ -1,7 +1,7 @@
import { BlockEnum } from '../../types'
import type { NodeDefault } from '../../types'
import type { TemplateTransformNodeType } from './types'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks'
const i18nPrefix = 'workflow.errorMsg'
const nodeDefault: NodeDefault<TemplateTransformNodeType> = {

View File

@ -2,7 +2,7 @@ import { BlockEnum } from '../../types'
import type { NodeDefault } from '../../types'
import type { ToolNodeType } from './types'
import { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks'
const i18nPrefix = 'workflow.errorMsg'

View File

@ -1,7 +1,7 @@
import { type NodeDefault, VarType } from '../../types'
import { BlockEnum } from '../../types'
import type { VariableAssignerNodeType } from './types'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants'
import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks'
const i18nPrefix = 'workflow'