mirror of https://github.com/langgenius/dify.git
UI enhancements for workflow checklist component (#24647)
This commit is contained in:
parent
c90dad566f
commit
add6b79231
|
|
@ -192,7 +192,7 @@ const AppPublisher = ({
|
|||
<PortalToFollowElemTrigger onClick={handleTrigger}>
|
||||
<Button
|
||||
variant='primary'
|
||||
className='p-2'
|
||||
className='py-2 pl-3 pr-2'
|
||||
disabled={disabled}
|
||||
>
|
||||
{t('workflow.common.publish')}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.43295 1.50009L11.1961 9.7501C11.3342 9.98925 11.2523 10.295 11.0131 10.4331C10.9371 10.477 10.8509 10.5001 10.7631 10.5001H1.23682C0.960676 10.5001 0.736816 10.2762 0.736816 10.0001C0.736816 9.9123 0.759921 9.8261 0.803806 9.7501L5.56695 1.50009C5.705 1.26094 6.0108 1.179 6.24995 1.31707C6.32595 1.36096 6.3891 1.42408 6.43295 1.50009ZM5.49995 8.0001V9.0001H6.49995V8.0001H5.49995ZM5.49995 4.50008V7.0001H6.49995V4.50008H5.49995Z" fill="#F79009"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 564 B |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9.43341 6.41661L6.30441 3.2876L7.12936 2.46265L11.6666 6.99994L7.12936 11.5372L6.30441 10.7122L9.43341 7.58327H2.33331V6.41661H9.43341Z" fill="#155AEF"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 267 B |
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"icon": {
|
||||
"type": "element",
|
||||
"isRootNode": true,
|
||||
"name": "svg",
|
||||
"attributes": {
|
||||
"width": "12",
|
||||
"height": "12",
|
||||
"viewBox": "0 0 12 12",
|
||||
"fill": "none",
|
||||
"xmlns": "http://www.w3.org/2000/svg"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M6.43295 1.50009L11.1961 9.7501C11.3342 9.98925 11.2523 10.295 11.0131 10.4331C10.9371 10.477 10.8509 10.5001 10.7631 10.5001H1.23682C0.960676 10.5001 0.736816 10.2762 0.736816 10.0001C0.736816 9.9123 0.759921 9.8261 0.803806 9.7501L5.56695 1.50009C5.705 1.26094 6.0108 1.179 6.24995 1.31707C6.32595 1.36096 6.3891 1.42408 6.43295 1.50009ZM5.49995 8.0001V9.0001H6.49995V8.0001H5.49995ZM5.49995 4.50008V7.0001H6.49995V4.50008H5.49995Z",
|
||||
"fill": "currentColor"
|
||||
},
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "Warning"
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './Warning.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement> & {
|
||||
ref?: React.RefObject<React.MutableRefObject<HTMLOrSVGElement>>;
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'Warning'
|
||||
|
||||
export default Icon
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
export { default as AlertTriangle } from './AlertTriangle'
|
||||
export { default as ThumbsDown } from './ThumbsDown'
|
||||
export { default as ThumbsUp } from './ThumbsUp'
|
||||
export { default as Warning } from './Warning'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"icon": {
|
||||
"type": "element",
|
||||
"isRootNode": true,
|
||||
"name": "svg",
|
||||
"attributes": {
|
||||
"width": "14",
|
||||
"height": "14",
|
||||
"viewBox": "0 0 14 14",
|
||||
"fill": "none",
|
||||
"xmlns": "http://www.w3.org/2000/svg"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M9.43341 6.41661L6.30441 3.2876L7.12936 2.46265L11.6666 6.99994L7.12936 11.5372L6.30441 10.7122L9.43341 7.58327H2.33331V6.41661H9.43341Z",
|
||||
"fill": "currentColor"
|
||||
},
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "IconR"
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './IconR.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement> & {
|
||||
ref?: React.RefObject<React.MutableRefObject<HTMLOrSVGElement>>;
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'IconR'
|
||||
|
||||
export default Icon
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
export { default as IconR } from './IconR'
|
||||
export { default as ArrowNarrowLeft } from './ArrowNarrowLeft'
|
||||
export { default as ArrowUpRight } from './ArrowUpRight'
|
||||
export { default as ChevronDownDouble } from './ChevronDownDouble'
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import { useCallback, useEffect } from 'react'
|
||||
import { useStoreApi } from 'reactflow'
|
||||
import { useWorkflowStore } from '@/app/components/workflow/store'
|
||||
import { BlockEnum } from '@/app/components/workflow/types'
|
||||
|
||||
export const useAutoOnboarding = () => {
|
||||
const store = useStoreApi()
|
||||
|
|
@ -22,19 +21,13 @@ export const useAutoOnboarding = () => {
|
|||
return
|
||||
|
||||
const nodes = getNodes()
|
||||
const startNodeTypes = [
|
||||
BlockEnum.Start,
|
||||
BlockEnum.TriggerSchedule,
|
||||
BlockEnum.TriggerWebhook,
|
||||
BlockEnum.TriggerPlugin,
|
||||
]
|
||||
|
||||
// Check if canvas is empty (no nodes or no start nodes)
|
||||
const hasStartNode = nodes.some(node => startNodeTypes.includes(node.data.type))
|
||||
const isEmpty = nodes.length === 0 || !hasStartNode
|
||||
// Check if canvas is completely empty (no nodes at all)
|
||||
// Only trigger onboarding when canvas is completely blank to avoid data loss
|
||||
const isCompletelyEmpty = nodes.length === 0
|
||||
|
||||
// Show onboarding if canvas is empty and we haven't shown it before in this session
|
||||
if (isEmpty && !hasShownOnboarding) {
|
||||
// Show onboarding only if canvas is completely empty and we haven't shown it before in this session
|
||||
if (isCompletelyEmpty && !hasShownOnboarding) {
|
||||
setShowOnboarding(true)
|
||||
setHasShownOnboarding(true)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ import {
|
|||
import {
|
||||
ChecklistSquare,
|
||||
} from '@/app/components/base/icons/src/vender/line/general'
|
||||
import { AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
|
||||
import { Warning } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
|
||||
import { IconR } from '@/app/components/base/icons/src/vender/line/arrows'
|
||||
|
||||
type WorkflowChecklistProps = {
|
||||
disabled: boolean
|
||||
|
|
@ -93,17 +94,17 @@ const WorkflowChecklist = ({
|
|||
<RiCloseLine className='h-4 w-4 text-text-tertiary' />
|
||||
</div>
|
||||
</div>
|
||||
<div className='py-2'>
|
||||
<div className='pb-2'>
|
||||
{
|
||||
!!needWarningNodes.length && (
|
||||
<>
|
||||
<div className='px-4 text-xs text-text-tertiary'>{t('workflow.panel.checklistTip')}</div>
|
||||
<div className='px-4 pt-1 text-xs text-text-tertiary'>{t('workflow.panel.checklistTip')}</div>
|
||||
<div className='px-4 py-2'>
|
||||
{
|
||||
needWarningNodes.map(node => (
|
||||
<div
|
||||
key={node.id}
|
||||
className='mb-2 cursor-pointer rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xs last-of-type:mb-0'
|
||||
className='group mb-2 cursor-pointer rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xs last-of-type:mb-0'
|
||||
onClick={() => {
|
||||
handleNodeSelect(node.id)
|
||||
setOpen(false)
|
||||
|
|
@ -118,13 +119,24 @@ const WorkflowChecklist = ({
|
|||
<span className='grow truncate'>
|
||||
{node.title}
|
||||
</span>
|
||||
<div className='flex h-4 w-[50px] items-center justify-center gap-1 opacity-0 transition-opacity duration-200 group-hover:opacity-100'>
|
||||
<span className='text-xs font-medium leading-4 text-primary-600'>
|
||||
{t('workflow.panel.goTo')}
|
||||
</span>
|
||||
<IconR className='h-3.5 w-3.5 text-primary-600' />
|
||||
</div>
|
||||
</div>
|
||||
<div className='border-t-[0.5px] border-divider-regular'>
|
||||
<div
|
||||
className={cn(
|
||||
'rounded-b-lg border-t-[0.5px] border-divider-regular',
|
||||
(node.unConnected || node.errorMessage) && 'bg-gradient-to-r from-components-badge-bg-orange-soft to-transparent',
|
||||
)}
|
||||
>
|
||||
{
|
||||
node.unConnected && (
|
||||
<div className='px-3 py-2 last:rounded-b-lg'>
|
||||
<div className='flex text-xs leading-[18px] text-text-tertiary'>
|
||||
<AlertTriangle className='mr-2 mt-[3px] h-3 w-3 text-[#F79009]' />
|
||||
<div className='px-3 py-1 first:pt-1.5 last:pb-1.5'>
|
||||
<div className='flex text-xs leading-4 text-text-tertiary'>
|
||||
<Warning className='mr-2 mt-[2px] h-3 w-3 text-[#F79009]' />
|
||||
{t('workflow.common.needConnectTip')}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -132,9 +144,9 @@ const WorkflowChecklist = ({
|
|||
}
|
||||
{
|
||||
node.errorMessage && (
|
||||
<div className='px-3 py-2 last:rounded-b-lg'>
|
||||
<div className='flex text-xs leading-[18px] text-text-tertiary'>
|
||||
<AlertTriangle className='mr-2 mt-[3px] h-3 w-3 text-[#F79009]' />
|
||||
<div className='px-3 py-1 first:pt-1.5 last:pb-1.5'>
|
||||
<div className='flex text-xs leading-4 text-text-tertiary'>
|
||||
<Warning className='mr-2 mt-[2px] h-3 w-3 text-[#F79009]' />
|
||||
{node.errorMessage}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -342,6 +342,7 @@ const translation = {
|
|||
checklist: 'Checklist',
|
||||
checklistTip: 'Make sure all issues are resolved before publishing',
|
||||
checklistResolved: 'All issues are resolved',
|
||||
goTo: 'Go to',
|
||||
startNode: 'Start Node',
|
||||
organizeBlocks: 'Organize nodes',
|
||||
change: 'Change',
|
||||
|
|
|
|||
|
|
@ -342,6 +342,7 @@ const translation = {
|
|||
checklist: 'チェックリスト',
|
||||
checklistTip: '公開前に全ての項目を確認してください',
|
||||
checklistResolved: '全てのチェックが完了しました',
|
||||
goTo: '移動',
|
||||
startNode: '開始ノード',
|
||||
organizeBlocks: 'ノード整理',
|
||||
change: '変更',
|
||||
|
|
|
|||
|
|
@ -342,6 +342,7 @@ const translation = {
|
|||
checklist: '检查清单',
|
||||
checklistTip: '发布前确保所有问题均已解决',
|
||||
checklistResolved: '所有问题均已解决',
|
||||
goTo: '转到',
|
||||
startNode: '开始节点',
|
||||
organizeBlocks: '整理节点',
|
||||
change: '更改',
|
||||
|
|
|
|||
Loading…
Reference in New Issue