Commit 8f3d9d01 authored by StyleZhang's avatar StyleZhang

panel

parent 344e30be
...@@ -66,6 +66,7 @@ const BlockIcon: FC<BlockIconProps> = ({ ...@@ -66,6 +66,7 @@ const BlockIcon: FC<BlockIconProps> = ({
flex items-center justify-center border-[0.5px] border-white/[0.02] text-white flex items-center justify-center border-[0.5px] border-white/[0.02] text-white
${ICON_CONTAINER_CLASSNAME_SIZE_MAP[size]} ${ICON_CONTAINER_CLASSNAME_SIZE_MAP[size]}
${ICON_CONTAINER_BG_COLOR_MAP[type]} ${ICON_CONTAINER_BG_COLOR_MAP[type]}
${icon && '!shadow-none'}
${className} ${className}
`} `}
> >
......
...@@ -7,6 +7,7 @@ import { ...@@ -7,6 +7,7 @@ import {
useCallback, useCallback,
useState, useState,
} from 'react' } from 'react'
import { useTranslation } from 'react-i18next'
import type { import type {
OffsetOptions, OffsetOptions,
Placement, Placement,
...@@ -47,6 +48,7 @@ const NodeSelector: FC<NodeSelectorProps> = ({ ...@@ -47,6 +48,7 @@ const NodeSelector: FC<NodeSelectorProps> = ({
popupClassName, popupClassName,
asChild, asChild,
}) => { }) => {
const { t } = useTranslation()
const [localOpen, setLocalOpen] = useState(false) const [localOpen, setLocalOpen] = useState(false)
const open = openFromProps === undefined ? localOpen : openFromProps const open = openFromProps === undefined ? localOpen : openFromProps
const handleOpenChange = useCallback((newOpen: boolean) => { const handleOpenChange = useCallback((newOpen: boolean) => {
...@@ -95,11 +97,14 @@ const NodeSelector: FC<NodeSelectorProps> = ({ ...@@ -95,11 +97,14 @@ const NodeSelector: FC<NodeSelectorProps> = ({
<PortalToFollowElemContent className='z-[1000]'> <PortalToFollowElemContent className='z-[1000]'>
<div className={`w-[256px] rounded-lg border-[0.5px] border-gray-200 bg-white shadow-lg ${popupClassName}`}> <div className={`w-[256px] rounded-lg border-[0.5px] border-gray-200 bg-white shadow-lg ${popupClassName}`}>
<div className='px-2 pt-2'> <div className='px-2 pt-2'>
<div className='flex items-center px-2 rounded-lg bg-gray-100'> <div
className='flex items-center px-2 rounded-lg bg-gray-100'
onClick={e => e.stopPropagation()}
>
<SearchLg className='shrink-0 ml-[1px] mr-[5px] w-3.5 h-3.5 text-gray-400' /> <SearchLg className='shrink-0 ml-[1px] mr-[5px] w-3.5 h-3.5 text-gray-400' />
<input <input
className='grow px-0.5 py-[7px] text-[13px] bg-transparent appearance-none outline-none' className='grow px-0.5 py-[7px] text-[13px] bg-transparent appearance-none outline-none'
placeholder='Search block' placeholder={t('workflow.tabs.searchBlock') || ''}
/> />
</div> </div>
</div> </div>
......
...@@ -3,9 +3,10 @@ import { ...@@ -3,9 +3,10 @@ import {
memo, memo,
useState, useState,
} from 'react' } from 'react'
import { useTranslation } from 'react-i18next'
import { groupBy } from 'lodash-es' import { groupBy } from 'lodash-es'
import BlockIcon from '../block-icon' import BlockIcon from '../block-icon'
import type { BlockEnum } from '../types' import { BlockEnum } from '../types'
import { BLOCK_CLASSIFICATIONS } from './constants' import { BLOCK_CLASSIFICATIONS } from './constants'
import { import {
useBlocks, useBlocks,
...@@ -14,6 +15,7 @@ import { ...@@ -14,6 +15,7 @@ import {
import type { ToolDefaultValue } from './types' import type { ToolDefaultValue } from './types'
import { TabsEnum } from './types' import { TabsEnum } from './types'
import Tools from './tools' import Tools from './tools'
import { useStore as useAppStore } from '@/app/components/app/store'
export type TabsProps = { export type TabsProps = {
onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void
...@@ -21,6 +23,8 @@ export type TabsProps = { ...@@ -21,6 +23,8 @@ export type TabsProps = {
const Tabs: FC<TabsProps> = ({ const Tabs: FC<TabsProps> = ({
onSelect, onSelect,
}) => { }) => {
const { t } = useTranslation()
const appDetail = useAppStore(state => state.appDetail)
const blocks = useBlocks() const blocks = useBlocks()
const tabs = useTabs() const tabs = useTabs()
const [activeTab, setActiveTab] = useState(tabs[0].key) const [activeTab, setActiveTab] = useState(tabs[0].key)
...@@ -55,12 +59,17 @@ const Tabs: FC<TabsProps> = ({ ...@@ -55,12 +59,17 @@ const Tabs: FC<TabsProps> = ({
{ {
classification !== '-' && ( classification !== '-' && (
<div className='flex items-start px-3 h-[22px] text-xs font-medium text-gray-500'> <div className='flex items-start px-3 h-[22px] text-xs font-medium text-gray-500'>
{classification} {t(`workflow.tabs.${classification}`)}
</div> </div>
) )
} }
{ {
groupBy(blocks, 'classification')[classification].map(block => ( groupBy(blocks, 'classification')[classification].filter((block) => {
if (block.type === BlockEnum.DirectAnswer && appDetail?.mode === 'workflow')
return false
return true
}).map(block => (
<div <div
key={block.type} key={block.type}
className='flex items-center px-3 h-8 rounded-lg hover:bg-gray-50 cursor-pointer' className='flex items-center px-3 h-8 rounded-lg hover:bg-gray-50 cursor-pointer'
......
...@@ -85,9 +85,9 @@ const Item = ({ ...@@ -85,9 +85,9 @@ const Item = ({
} }
<div <div
className='grow mr-2 truncate text-sm text-gray-900' className='grow mr-2 truncate text-sm text-gray-900'
title={data.name} title={data.label[language]}
> >
{data.name} {data.label[language]}
</div> </div>
{ {
data.expanded data.expanded
......
...@@ -2,6 +2,7 @@ import { ...@@ -2,6 +2,7 @@ import {
memo, memo,
useCallback, useCallback,
} from 'react' } from 'react'
import { useTranslation } from 'react-i18next'
import { useWorkflow } from '@/app/components/workflow/hooks' import { useWorkflow } from '@/app/components/workflow/hooks'
import BlockSelector from '@/app/components/workflow/block-selector' import BlockSelector from '@/app/components/workflow/block-selector'
import { Plus } from '@/app/components/base/icons/src/vender/line/general' import { Plus } from '@/app/components/base/icons/src/vender/line/general'
...@@ -17,6 +18,7 @@ const Add = ({ ...@@ -17,6 +18,7 @@ const Add = ({
sourceHandle, sourceHandle,
branchName, branchName,
}: AddProps) => { }: AddProps) => {
const { t } = useTranslation()
const { handleNodeAddNext } = useWorkflow() const { handleNodeAddNext } = useWorkflow()
const handleSelect = useCallback<OnSelectBlock>((type, toolDefaultValue) => { const handleSelect = useCallback<OnSelectBlock>((type, toolDefaultValue) => {
...@@ -42,10 +44,10 @@ const Add = ({ ...@@ -42,10 +44,10 @@ const Add = ({
<div className='flex items-center justify-center mr-1.5 w-5 h-5 rounded-[5px] bg-gray-200'> <div className='flex items-center justify-center mr-1.5 w-5 h-5 rounded-[5px] bg-gray-200'>
<Plus className='w-3 h-3' /> <Plus className='w-3 h-3' />
</div> </div>
SELECT NEXT BLOCK {t('workflow.panel.selectNextStep')}
</div> </div>
) )
}, [branchName]) }, [branchName, t])
return ( return (
<BlockSelector <BlockSelector
......
...@@ -2,6 +2,7 @@ import { ...@@ -2,6 +2,7 @@ import {
memo, memo,
useCallback, useCallback,
} from 'react' } from 'react'
import { useTranslation } from 'react-i18next'
import BlockSelector from '@/app/components/workflow/block-selector' import BlockSelector from '@/app/components/workflow/block-selector'
import { useWorkflow } from '@/app/components/workflow/hooks' import { useWorkflow } from '@/app/components/workflow/hooks'
import type { OnSelectBlock } from '@/app/components/workflow/types' import type { OnSelectBlock } from '@/app/components/workflow/types'
...@@ -14,6 +15,7 @@ const ChangeBlock = ({ ...@@ -14,6 +15,7 @@ const ChangeBlock = ({
nodeId, nodeId,
sourceHandle, sourceHandle,
}: ChangeBlockProps) => { }: ChangeBlockProps) => {
const { t } = useTranslation()
const { handleNodeChange } = useWorkflow() const { handleNodeChange } = useWorkflow()
const handleSelect = useCallback<OnSelectBlock>((type, toolDefaultValue) => { const handleSelect = useCallback<OnSelectBlock>((type, toolDefaultValue) => {
...@@ -23,10 +25,10 @@ const ChangeBlock = ({ ...@@ -23,10 +25,10 @@ const ChangeBlock = ({
const renderTrigger = useCallback(() => { const renderTrigger = useCallback(() => {
return ( return (
<div className='flex items-center px-3 w-[232px] h-8 text-sm text-gray-700 rounded-lg cursor-pointer hover:bg-gray-50'> <div className='flex items-center px-3 w-[232px] h-8 text-sm text-gray-700 rounded-lg cursor-pointer hover:bg-gray-50'>
Change Block {t('workflow.panel.changeBlock')}
</div> </div>
) )
}, []) }, [t])
return ( return (
<BlockSelector <BlockSelector
......
...@@ -2,6 +2,7 @@ import { ...@@ -2,6 +2,7 @@ import {
memo, memo,
useState, useState,
} from 'react' } from 'react'
import { useTranslation } from 'react-i18next'
import { useEdges } from 'reactflow' import { useEdges } from 'reactflow'
import ChangeBlock from './change-block' import ChangeBlock from './change-block'
import { useWorkflow } from '@/app/components/workflow/hooks' import { useWorkflow } from '@/app/components/workflow/hooks'
...@@ -21,6 +22,7 @@ const PanelOperator = ({ ...@@ -21,6 +22,7 @@ const PanelOperator = ({
id, id,
data, data,
}: PanelOperatorProps) => { }: PanelOperatorProps) => {
const { t } = useTranslation()
const edges = useEdges() const edges = useEdges()
const { handleNodeDelete } = useWorkflow() const { handleNodeDelete } = useWorkflow()
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
...@@ -55,7 +57,9 @@ const PanelOperator = ({ ...@@ -55,7 +57,9 @@ const PanelOperator = ({
nodeId={id} nodeId={id}
sourceHandle={edge?.sourceHandle || 'source'} sourceHandle={edge?.sourceHandle || 'source'}
/> />
<div className='flex items-center px-3 h-8 text-sm text-gray-700 rounded-lg cursor-pointer hover:bg-gray-50'>Help Link</div> <div className='flex items-center px-3 h-8 text-sm text-gray-700 rounded-lg cursor-pointer hover:bg-gray-50'>
{t('workflow.panel.helpLink')}
</div>
</div> </div>
<div className='h-[1px] bg-gray-100'></div> <div className='h-[1px] bg-gray-100'></div>
<div className='p-1'> <div className='p-1'>
...@@ -63,19 +67,19 @@ const PanelOperator = ({ ...@@ -63,19 +67,19 @@ const PanelOperator = ({
className='flex items-center px-3 h-8 text-sm text-gray-700 rounded-lg cursor-pointer hover:bg-gray-50' className='flex items-center px-3 h-8 text-sm text-gray-700 rounded-lg cursor-pointer hover:bg-gray-50'
onClick={() => handleNodeDelete(id)} onClick={() => handleNodeDelete(id)}
> >
Delete {t('common.operation.delete')}
</div> </div>
</div> </div>
<div className='h-[1px] bg-gray-100'></div> <div className='h-[1px] bg-gray-100'></div>
<div className='p-1'> <div className='p-1'>
<div className='px-3 py-2 text-xs text-gray-500'> <div className='px-3 py-2 text-xs text-gray-500'>
<div className='flex items-center mb-1 h-[22px] font-medium'> <div className='flex items-center mb-1 h-[22px] font-medium'>
ABOUT {t('workflow.panel.about')}
</div> </div>
<div className='text-gray-500 leading-[18px]'>{data._about}</div> <div className='text-gray-500 leading-[18px]'>{data._about}</div>
<div className='my-2 h-[0.5px] bg-black/5'></div> <div className='my-2 h-[0.5px] bg-black/5'></div>
<div className='leading-[18px]'> <div className='leading-[18px]'>
Created By {data._author} {t('workflow.panel.createdBy')} {data._author}
</div> </div>
</div> </div>
</div> </div>
......
...@@ -7,6 +7,7 @@ import { ...@@ -7,6 +7,7 @@ import {
memo, memo,
useCallback, useCallback,
} from 'react' } from 'react'
import { useTranslation } from 'react-i18next'
import NextStep from './components/next-step' import NextStep from './components/next-step'
import PanelOperator from './components/panel-operator' import PanelOperator from './components/panel-operator'
import { import {
...@@ -34,6 +35,7 @@ const BasePanel: FC<BasePanelProps> = ({ ...@@ -34,6 +35,7 @@ const BasePanel: FC<BasePanelProps> = ({
data, data,
children, children,
}) => { }) => {
const { t } = useTranslation()
const { const {
handleNodeSelect, handleNodeSelect,
handleNodeDataUpdate, handleNodeDataUpdate,
...@@ -63,7 +65,7 @@ const BasePanel: FC<BasePanelProps> = ({ ...@@ -63,7 +65,7 @@ const BasePanel: FC<BasePanelProps> = ({
{ {
canRunBySingle(data.type) && ( canRunBySingle(data.type) && (
<TooltipPlus <TooltipPlus
popupContent='Run this step' popupContent={t('workflow.panel.runThisStep')}
> >
<div <div
className='flex items-center justify-center mr-1 w-6 h-6 rounded-md hover:bg-black/5 cursor-pointer' className='flex items-center justify-center mr-1 w-6 h-6 rounded-md hover:bg-black/5 cursor-pointer'
...@@ -99,10 +101,10 @@ const BasePanel: FC<BasePanelProps> = ({ ...@@ -99,10 +101,10 @@ const BasePanel: FC<BasePanelProps> = ({
<div className='p-4 border-t-[0.5px] border-t-black/5'> <div className='p-4 border-t-[0.5px] border-t-black/5'>
<div className='flex items-center mb-1 text-gray-700 text-[13px] font-semibold'> <div className='flex items-center mb-1 text-gray-700 text-[13px] font-semibold'>
<GitBranch01 className='mr-1 w-4 h-4' /> <GitBranch01 className='mr-1 w-4 h-4' />
NEXT STEP {t('workflow.panel.nextStep').toLocaleUpperCase()}
</div> </div>
<div className='mb-2 text-xs text-gray-400'> <div className='mb-2 text-xs text-gray-400'>
Add the next block in this workflow {t('workflow.panel.addNextStep')}
</div> </div>
<NextStep selectedNode={{ id, data } as Node} /> <NextStep selectedNode={{ id, data } as Node} />
</div> </div>
......
import type { FC } from 'react' import type { FC } from 'react'
import { memo } from 'react' import { memo } from 'react'
import { useTranslation } from 'react-i18next'
import BlockIcon from '../block-icon' import BlockIcon from '../block-icon'
import { BlockEnum } from '../types' import { BlockEnum } from '../types'
import { AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback' import { AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
...@@ -8,6 +9,7 @@ import { useStore as useAppStore } from '@/app/components/app/store' ...@@ -8,6 +9,7 @@ import { useStore as useAppStore } from '@/app/components/app/store'
import AppIcon from '@/app/components/base/app-icon' import AppIcon from '@/app/components/base/app-icon'
const WorkflowInfo: FC = () => { const WorkflowInfo: FC = () => {
const { t } = useTranslation()
const appDetail = useAppStore(state => state.appDetail) const appDetail = useAppStore(state => state.appDetail)
if (!appDetail) if (!appDetail)
...@@ -32,12 +34,12 @@ const WorkflowInfo: FC = () => { ...@@ -32,12 +34,12 @@ const WorkflowInfo: FC = () => {
</div> </div>
<div className='flex items-center px-4 h-[42px] text-[13px] font-semibold text-gray-700'> <div className='flex items-center px-4 h-[42px] text-[13px] font-semibold text-gray-700'>
<FileCheck02 className='mr-1 w-4 h-4' /> <FileCheck02 className='mr-1 w-4 h-4' />
Checklist(2) {t('workflow.panel.checklist')}(2)
</div> </div>
</div> </div>
<div className='py-2'> <div className='py-2'>
<div className='px-4 py-2 text-xs text-gray-400'> <div className='px-4 py-2 text-xs text-gray-400'>
Make sure all issues are resolved before publishing {t('workflow.panel.checklistTip')}
</div> </div>
<div className='px-4 py-2'> <div className='px-4 py-2'>
<div className='border-[0.5px] border-gray-200 bg-white shadow-xs rounded-lg'> <div className='border-[0.5px] border-gray-200 bg-white shadow-xs rounded-lg'>
......
...@@ -23,9 +23,14 @@ const translation = { ...@@ -23,9 +23,14 @@ const translation = {
restore: 'Restore', restore: 'Restore',
}, },
tabs: { tabs: {
blocks: 'Blocks', 'searchBlock': 'Search block',
builtInTool: 'Built-in Tool', 'blocks': 'Blocks',
customTool: 'Custom Tool', 'builtInTool': 'Built-in Tool',
'customTool': 'Custom Tool',
'question-understand': 'Question Understand',
'logic': 'Logic',
'transform': 'Transform',
'utilities': 'Utilities',
}, },
blocks: { blocks: {
'start': 'Start', 'start': 'Start',
...@@ -49,6 +54,16 @@ const translation = { ...@@ -49,6 +54,16 @@ const translation = {
}, },
panel: { panel: {
userInputField: 'User Input Field', userInputField: 'User Input Field',
changeBlock: 'Change Block',
helpLink: 'Help Link',
about: 'About',
createdBy: 'Created By ',
nextStep: 'Next Step',
addNextStep: 'Add the next block in this workflow',
selectNextStep: 'Select Next Block',
runThisStep: 'Run this step',
checklist: 'Checklist',
checklistTip: 'Make sure all issues are resolved before publishing',
}, },
nodes: { nodes: {
common: { common: {
......
...@@ -23,9 +23,14 @@ const translation = { ...@@ -23,9 +23,14 @@ const translation = {
restore: '恢复', restore: '恢复',
}, },
tabs: { tabs: {
blocks: 'Blocks', 'searchBlock': '搜索节点',
builtInTool: '内置工具', 'blocks': '节点',
customTool: '自定义工具', 'builtInTool': '内置工具',
'customTool': '自定义工具',
'question-understand': '问题理解',
'logic': '逻辑',
'transform': '转换',
'utilities': '工具',
}, },
blocks: { blocks: {
'start': '开始', 'start': '开始',
...@@ -49,6 +54,16 @@ const translation = { ...@@ -49,6 +54,16 @@ const translation = {
}, },
panel: { panel: {
userInputField: '用户输入字段', userInputField: '用户输入字段',
changeBlock: '更改节点',
helpLink: '帮助链接',
about: '关于',
createdBy: '作者',
nextStep: '下一步',
addNextStep: '添加此工作流程中的下一个节点',
selectNextStep: '选择下一个节点',
runThisStep: '运行此步骤',
checklist: '检查清单',
checklistTip: '发布前确保所有问题均已解决',
}, },
nodes: { nodes: {
common: { common: {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment