diff --git a/web/app/components/base/icons/assets/vender/line/development/git-branch-01.svg b/web/app/components/base/icons/assets/vender/line/development/git-branch-01.svg new file mode 100644 index 0000000000..1f4c7d2ad3 --- /dev/null +++ b/web/app/components/base/icons/assets/vender/line/development/git-branch-01.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/app/components/base/icons/assets/vender/line/general/log-in-04.svg b/web/app/components/base/icons/assets/vender/line/general/log-in-04.svg new file mode 100644 index 0000000000..f18c50c869 --- /dev/null +++ b/web/app/components/base/icons/assets/vender/line/general/log-in-04.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/app/components/base/icons/assets/vender/line/general/log-out-04.svg b/web/app/components/base/icons/assets/vender/line/general/log-out-04.svg new file mode 100644 index 0000000000..317023e95e --- /dev/null +++ b/web/app/components/base/icons/assets/vender/line/general/log-out-04.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/app/components/base/icons/src/vender/line/development/GitBranch01.json b/web/app/components/base/icons/src/vender/line/development/GitBranch01.json new file mode 100644 index 0000000000..04205e57c6 --- /dev/null +++ b/web/app/components/base/icons/src/vender/line/development/GitBranch01.json @@ -0,0 +1,39 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "16", + "height": "16", + "viewBox": "0 0 16 16", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "g", + "attributes": { + "id": "git-branch-01" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "id": "Icon", + "d": "M2 2V8.8C2 9.92011 2 10.4802 2.21799 10.908C2.40973 11.2843 2.71569 11.5903 3.09202 11.782C3.51984 12 4.0799 12 5.2 12H10M10 12C10 13.1046 10.8954 14 12 14C13.1046 14 14 13.1046 14 12C14 10.8954 13.1046 10 12 10C10.8954 10 10 10.8954 10 12ZM2 5.33333L10 5.33333M10 5.33333C10 6.4379 10.8954 7.33333 12 7.33333C13.1046 7.33333 14 6.4379 14 5.33333C14 4.22876 13.1046 3.33333 12 3.33333C10.8954 3.33333 10 4.22876 10 5.33333Z", + "stroke": "currentColor", + "stroke-width": "1.25", + "stroke-linecap": "round", + "stroke-linejoin": "round" + }, + "children": [] + } + ] + } + ] + }, + "name": "GitBranch01" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/vender/line/development/GitBranch01.tsx b/web/app/components/base/icons/src/vender/line/development/GitBranch01.tsx new file mode 100644 index 0000000000..e729beb2d3 --- /dev/null +++ b/web/app/components/base/icons/src/vender/line/development/GitBranch01.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './GitBranch01.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef, Omit>(( + props, + ref, +) => ) + +Icon.displayName = 'GitBranch01' + +export default Icon diff --git a/web/app/components/base/icons/src/vender/line/development/index.ts b/web/app/components/base/icons/src/vender/line/development/index.ts index 8ef8d98be8..0ec90983a1 100644 --- a/web/app/components/base/icons/src/vender/line/development/index.ts +++ b/web/app/components/base/icons/src/vender/line/development/index.ts @@ -3,6 +3,7 @@ export { default as BracketsX } from './BracketsX' export { default as Container } from './Container' export { default as Database01 } from './Database01' export { default as Database03 } from './Database03' +export { default as GitBranch01 } from './GitBranch01' export { default as PuzzlePiece01 } from './PuzzlePiece01' export { default as Variable } from './Variable' export { default as Webhooks } from './Webhooks' diff --git a/web/app/components/base/icons/src/vender/line/general/LogIn04.json b/web/app/components/base/icons/src/vender/line/general/LogIn04.json new file mode 100644 index 0000000000..a8316e9c27 --- /dev/null +++ b/web/app/components/base/icons/src/vender/line/general/LogIn04.json @@ -0,0 +1,53 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "16", + "height": "16", + "viewBox": "0 0 16 16", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "g", + "attributes": { + "id": "log-in-04" + }, + "children": [ + { + "type": "element", + "name": "g", + "attributes": { + "id": "Solid" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "d": "M8.00016 1.99984C5.78015 1.99984 3.84088 3.20518 2.80244 5.00032C2.61808 5.31903 2.21026 5.42794 1.89155 5.24357C1.57285 5.05921 1.46394 4.65139 1.6483 4.33269C2.91526 2.14249 5.28495 0.666504 8.00016 0.666504C12.0502 0.666504 15.3335 3.94975 15.3335 7.99984C15.3335 12.0499 12.0502 15.3332 8.00016 15.3332C5.28495 15.3332 2.91526 13.8572 1.6483 11.667C1.46394 11.3483 1.57285 10.9405 1.89155 10.7561C2.21026 10.5717 2.61808 10.6806 2.80244 10.9994C3.84088 12.7945 5.78015 13.9998 8.00016 13.9998C11.3139 13.9998 14.0002 11.3135 14.0002 7.99984C14.0002 4.68613 11.3139 1.99984 8.00016 1.99984Z", + "fill": "currentColor" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M7.52876 4.86177C7.78911 4.60142 8.21122 4.60142 8.47157 4.86177L11.1382 7.52843C11.3986 7.78878 11.3986 8.21089 11.1382 8.47124L8.47157 11.1379C8.21122 11.3983 7.78911 11.3983 7.52876 11.1379C7.26841 10.8776 7.26841 10.4554 7.52876 10.1951L9.05735 8.6665H2.00016C1.63197 8.6665 1.3335 8.36803 1.3335 7.99984C1.3335 7.63165 1.63197 7.33317 2.00016 7.33317H9.05735L7.52876 5.80457C7.26841 5.54423 7.26841 5.12212 7.52876 4.86177Z", + "fill": "currentColor" + }, + "children": [] + } + ] + } + ] + } + ] + }, + "name": "LogIn04" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/vender/line/general/LogIn04.tsx b/web/app/components/base/icons/src/vender/line/general/LogIn04.tsx new file mode 100644 index 0000000000..14c3fa18f1 --- /dev/null +++ b/web/app/components/base/icons/src/vender/line/general/LogIn04.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './LogIn04.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef, Omit>(( + props, + ref, +) => ) + +Icon.displayName = 'LogIn04' + +export default Icon diff --git a/web/app/components/base/icons/src/vender/line/general/LogOut04.json b/web/app/components/base/icons/src/vender/line/general/LogOut04.json new file mode 100644 index 0000000000..a19bedfe4c --- /dev/null +++ b/web/app/components/base/icons/src/vender/line/general/LogOut04.json @@ -0,0 +1,53 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "16", + "height": "16", + "viewBox": "0 0 16 16", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "g", + "attributes": { + "id": "log-out-04" + }, + "children": [ + { + "type": "element", + "name": "g", + "attributes": { + "id": "Solid" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "d": "M0.666504 8.00016C0.666504 4.3422 3.52829 1.3335 7.11095 1.3335C8.28872 1.3335 9.3935 1.66091 10.3431 2.23137C10.6588 2.42097 10.7609 2.83053 10.5713 3.14615C10.3817 3.46177 9.97216 3.56394 9.65654 3.37434C8.90651 2.92378 8.03794 2.66683 7.11095 2.66683C4.31165 2.66683 1.99984 5.03071 1.99984 8.00016C1.99984 10.9696 4.31165 13.3335 7.11095 13.3335C8.03794 13.3335 8.90651 13.0765 9.65654 12.626C9.97216 12.4364 10.3817 12.5386 10.5713 12.8542C10.7609 13.1698 10.6588 13.5794 10.3431 13.769C9.3935 14.3394 8.28872 14.6668 7.11095 14.6668C3.52829 14.6668 0.666504 11.6581 0.666504 8.00016Z", + "fill": "currentColor" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M11.5284 4.86209C11.7888 4.60174 12.2109 4.60174 12.4712 4.86209L15.1379 7.52876C15.3983 7.78911 15.3983 8.21122 15.1379 8.47157L12.4712 11.1382C12.2109 11.3986 11.7888 11.3986 11.5284 11.1382C11.2681 10.8779 11.2681 10.4558 11.5284 10.1954L13.057 8.66683H5.99984C5.63165 8.66683 5.33317 8.36835 5.33317 8.00016C5.33317 7.63197 5.63165 7.3335 5.99984 7.3335H13.057L11.5284 5.8049C11.2681 5.54455 11.2681 5.12244 11.5284 4.86209Z", + "fill": "currentColor" + }, + "children": [] + } + ] + } + ] + } + ] + }, + "name": "LogOut04" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/vender/line/general/LogOut04.tsx b/web/app/components/base/icons/src/vender/line/general/LogOut04.tsx new file mode 100644 index 0000000000..954b90e932 --- /dev/null +++ b/web/app/components/base/icons/src/vender/line/general/LogOut04.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './LogOut04.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef, Omit>(( + props, + ref, +) => ) + +Icon.displayName = 'LogOut04' + +export default Icon diff --git a/web/app/components/base/icons/src/vender/line/general/index.ts b/web/app/components/base/icons/src/vender/line/general/index.ts index 0c1e8747ad..b487685fdf 100644 --- a/web/app/components/base/icons/src/vender/line/general/index.ts +++ b/web/app/components/base/icons/src/vender/line/general/index.ts @@ -13,7 +13,9 @@ export { default as Link03 } from './Link03' export { default as LinkExternal01 } from './LinkExternal01' export { default as LinkExternal02 } from './LinkExternal02' export { default as Loading02 } from './Loading02' +export { default as LogIn04 } from './LogIn04' export { default as LogOut01 } from './LogOut01' +export { default as LogOut04 } from './LogOut04' export { default as Menu01 } from './Menu01' export { default as Pin01 } from './Pin01' export { default as Pin02 } from './Pin02' diff --git a/web/app/components/workflow/block-icon.tsx b/web/app/components/workflow/block-icon.tsx index d65c46513c..23fc8f7960 100644 --- a/web/app/components/workflow/block-icon.tsx +++ b/web/app/components/workflow/block-icon.tsx @@ -1,4 +1,5 @@ import type { FC } from 'react' +import { memo } from 'react' import { BlockEnum } from './types' import { Code, @@ -67,4 +68,4 @@ const BlockIcon: FC = ({ ) } -export default BlockIcon +export default memo(BlockIcon) diff --git a/web/app/components/workflow/block-selector/constants.tsx b/web/app/components/workflow/block-selector/constants.tsx index 1ad17b838a..206752b121 100644 --- a/web/app/components/workflow/block-selector/constants.tsx +++ b/web/app/components/workflow/block-selector/constants.tsx @@ -1,3 +1,4 @@ +import { groupBy } from 'lodash-es' import type { Block } from '../types' import { BlockEnum } from '../types' @@ -16,57 +17,79 @@ export const TABS = [ }, ] +export enum BlockClassificationEnum { + Default = '-', + QuestionUnderstand = 'question-understand', + Logic = 'logic', + Transform = 'transform', + Utilities = 'utilities', +} + export const BLOCKS: Block[] = [ { + classification: BlockClassificationEnum.Default, type: BlockEnum.Start, title: 'Start', description: '', }, { + classification: BlockClassificationEnum.Default, type: BlockEnum.LLM, title: 'LLM', }, { + classification: BlockClassificationEnum.Default, type: BlockEnum.End, title: 'End', }, { + classification: BlockClassificationEnum.Default, type: BlockEnum.DirectAnswer, title: 'Direct Answer', }, { - classification: 'Question Understand', + classification: BlockClassificationEnum.QuestionUnderstand, type: BlockEnum.KnowledgeRetrieval, title: 'Knowledge Retrieval', }, { - classification: 'Question Understand', + classification: BlockClassificationEnum.QuestionUnderstand, type: BlockEnum.QuestionClassifier, title: 'Question Classifier', }, { - classification: 'Logic', + classification: BlockClassificationEnum.Logic, type: BlockEnum.IfElse, title: 'IF/ELSE', }, { - classification: 'Transform', + classification: BlockClassificationEnum.Transform, type: BlockEnum.Code, title: 'Code', }, { - classification: 'Transform', + classification: BlockClassificationEnum.Transform, type: BlockEnum.TemplateTransform, title: 'Templating Transform', }, { - classification: 'Transform', + classification: BlockClassificationEnum.Transform, type: BlockEnum.VariableAssigner, title: 'Variable Assigner', }, { - classification: 'Utilities', + classification: BlockClassificationEnum.Utilities, type: BlockEnum.HttpRequest, title: 'HTTP Request', }, ] + +export const BLOCK_CLASSIFICATIONS: string[] = [ + BlockClassificationEnum.Default, + BlockClassificationEnum.QuestionUnderstand, + BlockClassificationEnum.Logic, + BlockClassificationEnum.Transform, + BlockClassificationEnum.Utilities, +] + +export const BLOCK_GROUP_BY_CLASSIFICATION = groupBy(BLOCKS, 'classification') diff --git a/web/app/components/workflow/block-selector/index.tsx b/web/app/components/workflow/block-selector/index.tsx index b946d0f91f..be35a2f26a 100644 --- a/web/app/components/workflow/block-selector/index.tsx +++ b/web/app/components/workflow/block-selector/index.tsx @@ -33,7 +33,7 @@ const NodeSelector: FC = ({ {children} - +
diff --git a/web/app/components/workflow/block-selector/tabs.tsx b/web/app/components/workflow/block-selector/tabs.tsx index 3e42d169d0..c7c4ddb61e 100644 --- a/web/app/components/workflow/block-selector/tabs.tsx +++ b/web/app/components/workflow/block-selector/tabs.tsx @@ -1,7 +1,8 @@ import { useState } from 'react' import BlockIcon from '../block-icon' import { - BLOCKS, + BLOCK_CLASSIFICATIONS, + BLOCK_GROUP_BY_CLASSIFICATION, TABS, } from './constants' @@ -28,16 +29,32 @@ const Tabs = () => {
{ - BLOCKS.map(block => ( + BLOCK_CLASSIFICATIONS.map(classification => (
- -
{block.title}
+ { + classification !== '-' && ( +
+ {classification} +
+ ) + } + { + BLOCK_GROUP_BY_CLASSIFICATION[classification].map(block => ( +
+ +
{block.title}
+
+ )) + }
)) } diff --git a/web/app/components/workflow/block-selector/utils.ts b/web/app/components/workflow/block-selector/utils.ts new file mode 100644 index 0000000000..76b3f64d9b --- /dev/null +++ b/web/app/components/workflow/block-selector/utils.ts @@ -0,0 +1,6 @@ +import type { BlockEnum } from '../types' +import { BLOCKS } from './constants' + +export const getBlockByType = (type: BlockEnum) => { + return BLOCKS.find(block => block.type === type) +} diff --git a/web/app/components/workflow/nodes/_base/components/next-step.tsx b/web/app/components/workflow/nodes/_base/components/next-step.tsx new file mode 100644 index 0000000000..8fec842d1e --- /dev/null +++ b/web/app/components/workflow/nodes/_base/components/next-step.tsx @@ -0,0 +1,71 @@ +import type { FC } from 'react' +import { + memo, + useMemo, +} from 'react' +import { getOutgoers } from 'reactflow' +import BlockIcon from '../../../block-icon' +import type { Node } from '../../../types' +import { useWorkflowContext } from '../../../context' +import BlockSelector from '../../../block-selector' +import { Plus } from '@/app/components/base/icons/src/vender/line/general' +import Button from '@/app/components/base/button' + +type NextStepProps = { + selectedNode: Node +} +const NextStep: FC = ({ + selectedNode, +}) => { + const { + nodes, + edges, + } = useWorkflowContext() + const outgoers = useMemo(() => { + return getOutgoers(selectedNode, nodes, edges) + }, [selectedNode, nodes, edges]) + + return ( +
+
+ +
+
+
+ { + !outgoers.length && ( + +
+
+ +
+ SELECT NEXT BLOCK +
+
+ ) + } + { + !!outgoers.length && outgoers.map(outgoer => ( +
+ +
{outgoer.data.name}
+ + + +
+ )) + } +
+
+ ) +} + +export default memo(NextStep) diff --git a/web/app/components/workflow/nodes/_base/node.tsx b/web/app/components/workflow/nodes/_base/node.tsx index 669139e4d9..6482c6f1e4 100644 --- a/web/app/components/workflow/nodes/_base/node.tsx +++ b/web/app/components/workflow/nodes/_base/node.tsx @@ -9,6 +9,7 @@ import { } from 'reactflow' import { useWorkflowContext } from '../../context' import BlockSelector from '../../block-selector' +import { getBlockByType } from '../../block-selector/utils' import BlockIcon from '../../block-icon' import { Plus } from '@/app/components/base/icons/src/vender/line/general' @@ -48,7 +49,9 @@ const BaseNode: FC = ({ type={currentNode!.data.type} size='md' /> -
START
+
+ {getBlockByType(currentNode!.data.type)?.title} +
{children}
diff --git a/web/app/components/workflow/nodes/_base/panel.tsx b/web/app/components/workflow/nodes/_base/panel.tsx index 4b12c53b88..b0083c369f 100644 --- a/web/app/components/workflow/nodes/_base/panel.tsx +++ b/web/app/components/workflow/nodes/_base/panel.tsx @@ -5,7 +5,14 @@ import type { import { useState } from 'react' import { useWorkflowContext } from '../../context' import BlockIcon from '../../block-icon' -import { XClose } from '@/app/components/base/icons/src/vender/line/general' +import { getBlockByType } from '../../block-selector/utils' +import NextStep from './components/next-step' +import { + LogIn04, + LogOut04, + XClose, +} from '@/app/components/base/icons/src/vender/line/general' +import { GitBranch01 } from '@/app/components/base/icons/src/vender/line/development' enum TabEnum { Inputs = 'inputs', @@ -32,17 +39,17 @@ const BasePanel: FC = ({ return (
-
+
-
LLM
+
{getBlockByType(selectedNode!.data.type)?.title}
handleSelectedNodeIdChange('')} > @@ -56,24 +63,32 @@ const BasePanel: FC = ({
{ (inputsElement || outputsElement) && ( -
+
{ inputsElement && (
setActiveTab(TabEnum.Inputs)} > - inputs + + INPUTS + { + activeTab === TabEnum.Inputs &&
+ }
) } { outputsElement && (
setActiveTab(TabEnum.Outputs)} > - outpus + + OUTPUTS + { + activeTab === TabEnum.Outputs &&
+ }
) } @@ -81,13 +96,20 @@ const BasePanel: FC = ({ ) }
-
+
{defaultElement} {activeTab === TabEnum.Inputs && inputsElement} {activeTab === TabEnum.Outputs && outputsElement}
- next step +
+ + NEXT STEP +
+
+ Add the next block in this workflow +
+
)