Skip to content

Commit b2d358f

Browse files
authored
Merge pull request #231 from code0-tech/feat/#127
SubFlow pattern
2 parents 7411697 + 4686d76 commit b2d358f

24 files changed

Lines changed: 399 additions & 427 deletions

package-lock.json

Lines changed: 58 additions & 175 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"dependencies": {
1717
"@apollo/client": "^4.0.9",
1818
"@code0-tech/pictor": "^0.9.0",
19-
"@code0-tech/triangulum": "^0.16.0",
19+
"@code0-tech/triangulum": "^0.18.0",
2020
"@codemirror/lang-javascript": "^6.2.5",
2121
"@codemirror/lint": "^6.9.5",
2222
"@opentelemetry/api": "^1.9.1",

src/packages/ce/src/datatype/components/badges/NodeBadgeComponent.tsx

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
import {
2-
Flow,
3-
FlowType,
4-
FunctionDefinition,
5-
NodeFunction,
6-
NodeFunctionIdWrapper
7-
} from "@code0-tech/sagittarius-graphql-types";
1+
import {Flow, FlowType, FunctionDefinition, NodeFunction, SubFlowValue,} from "@code0-tech/sagittarius-graphql-types";
82
import React from "react";
93
import {Badge, BadgeType, hashToColor, Text, useService, useStore} from "@code0-tech/pictor";
104
import {FunctionService} from "@edition/function/services/Function.service";
@@ -15,7 +9,7 @@ import {icon, IconString} from "@core/util/icons";
159
import {FALLBACK_FLOW_TYPE_NAME, FALLBACK_FUNCTION_NAME} from "@core/util/fallback-translations";
1610

1711
export interface NodeBadgeComponentProps extends Omit<BadgeType, 'value' | 'children'> {
18-
value: NodeFunction | NodeFunctionIdWrapper
12+
value: SubFlowValue
1913
definition?: FunctionDefinition | FlowType
2014
}
2115

@@ -34,41 +28,34 @@ export const NodeBadgeComponent: React.FC<NodeBadgeComponentProps> = (props) =>
3428
const flowTypeService = definition || useService(FlowTypeService)
3529
const flowTypeStore = definition || useStore(FlowTypeService)
3630

37-
const isTrigger = value.__typename === "NodeFunctionIdWrapper" && !value.id
31+
const isTrigger = !value.startingNodeId && !value.functionDefinition?.identifier
3832

39-
const node: NodeFunction | FlowType | NodeFunctionIdWrapper | undefined = React.useMemo(() => {
33+
const lDefinition: FlowType | FunctionDefinition | undefined = React.useMemo(() => {
4034
if (isTrigger && !definition) {
4135
const flow = (flowService as FlowService).getById(flowId)
4236
return (flowTypeService as FlowTypeService).getById(flow?.type?.id)
4337
}
44-
return value.__typename === "NodeFunction" || definition ? value : (flowService as FlowService).getNodeById(flowId, value.id)
45-
}, [flowStore, flowTypeStore])
4638

47-
const name = React.useMemo(() => {
48-
if (definition) {
49-
return definition.names?.[0]?.content ?? (definition.__typename === "FunctionDefinition" ? FALLBACK_FUNCTION_NAME : FALLBACK_FLOW_TYPE_NAME)
50-
} else if (isTrigger && node?.__typename === "FlowType") {
51-
return node.names?.[0]?.content ?? FALLBACK_FLOW_TYPE_NAME
39+
if (value.__typename === "SubFlowValue" && !definition && value.startingNodeId) {
40+
const node = (flowService as FlowService).getNodeById(flowId, value.startingNodeId)
41+
return (functionService as FunctionService).getById(node?.functionDefinition?.id)
5242
}
53-
return (functionService as FunctionService).getById((node as NodeFunction)?.functionDefinition?.id)?.names?.[0]?.content ?? FALLBACK_FUNCTION_NAME
54-
}, [functionStore, node])
5543

56-
const lDefinition = React.useMemo(
57-
() => {
58-
if (definition) {
59-
return definition
60-
} else if (isTrigger && node?.__typename === "FlowType") {
61-
return node
62-
}
63-
return (functionService as FunctionService).getById((node as NodeFunction)?.functionDefinition?.id)
64-
},
65-
[functionStore, node]
66-
)
44+
if (value.__typename === "SubFlowValue" && !definition && value.functionDefinition?.id) {
45+
return (functionService as FunctionService).getById(value.functionDefinition?.id)
46+
47+
}
48+
return definition
49+
}, [flowStore, flowTypeStore])
50+
51+
const name = React.useMemo(() => {
52+
return lDefinition?.names?.[0].content ?? (lDefinition?.__typename === "FlowType" ? FALLBACK_FLOW_TYPE_NAME : FALLBACK_FUNCTION_NAME)
53+
}, [functionStore, lDefinition])
6754

6855
const DisplayIcon = icon(lDefinition?.displayIcon as IconString)
6956

7057
return <Badge style={{verticalAlign: "middle", textWrap: "nowrap"}}
71-
color={isTrigger ? "info" : hashToColor(value.id || "")}
58+
color={isTrigger ? "info" : hashToColor(value.startingNodeId || value.functionDefinition?.id || "")}
7259
border
7360
{...rest}>
7461
<DisplayIcon size={12}/>

src/packages/ce/src/datatype/components/badges/ReferenceBadgeComponent.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ export const ReferenceBadgeComponent: React.FC<ReferenceBadgeComponentProps> = (
2121
if (flowId) {
2222
return <Flex align={"center"} display={"inline-flex"}>
2323
<NodeBadgeComponent definition={definition} value={{
24-
id: value.nodeFunctionId,
25-
__typename: "NodeFunctionIdWrapper"
24+
startingNodeId: value.nodeFunctionId,
25+
__typename: "SubFlowValue"
2626
}}/>
2727
{"inputTypeIdentifier" in value && value.inputTypeIdentifier ? "." + value.inputTypeIdentifier : ""}
2828
{value.referencePath ? "." + (value.referencePath?.map(path => path.path).join(".") ?? "") : ""}

src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import React from "react";
22
import {DataTypeTextInputComponent} from "./text/DataTypeTextInputComponent";
33
import {NodeSchema} from "@code0-tech/triangulum";
4-
import {LiteralValue, NodeFunction, NodeParameterValue, ReferenceValue} from "@code0-tech/sagittarius-graphql-types";
4+
import {
5+
LiteralValue,
6+
NodeFunction,
7+
NodeParameterValue,
8+
ReferenceValue,
9+
SubFlowValue
10+
} from "@code0-tech/sagittarius-graphql-types";
511
import {DataTypeBooleanInputComponent} from "@edition/datatype/components/inputs/boolean/DataTypeBooleanInputComponent";
612
import {DataTypeSelectInputComponent} from "@edition/datatype/components/inputs/select/DataTypeSelectInputComponent";
713
import {InputWrapperProps} from "@code0-tech/pictor/dist/components/form/InputWrapper";
@@ -15,8 +21,8 @@ import {
1521
export interface DataTypeInputComponentProps extends Omit<InputWrapperProps<NodeParameterValue | NodeFunction>, "onChange"> {
1622
schema: NodeSchema
1723
clearable?: boolean
18-
onChange?: (value: ReferenceValue | LiteralValue | NodeFunction | undefined) => void
19-
suggestions?: (NodeFunction | ReferenceValue | LiteralValue)[]
24+
onChange?: (value: ReferenceValue | SubFlowValue | LiteralValue | NodeFunction | undefined) => void
25+
suggestions?: (NodeFunction | SubFlowValue | ReferenceValue | LiteralValue)[]
2026
onClear?: (event: React.MouseEvent<HTMLButtonElement>) => void
2127
}
2228

src/packages/ce/src/datatype/components/inputs/DataTypeInputControlsComponent.tsx

Lines changed: 54 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {LiteralValue, NodeFunction, ReferenceValue} from "@code0-tech/sagittarius-graphql-types";
1+
import {LiteralValue, NodeFunction, ReferenceValue, SubFlowValue} from "@code0-tech/sagittarius-graphql-types";
22
import React from "react";
33
import {IconVariable, IconX} from "@tabler/icons-react";
44
import {ReferenceBadgeComponent} from "@edition/datatype/components/badges/ReferenceBadgeComponent";
@@ -17,61 +17,72 @@ import {
1717
TooltipPortal,
1818
TooltipTrigger
1919
} from "@code0-tech/pictor"
20+
import {NodeBadgeComponent} from "@edition/datatype/components/badges/NodeBadgeComponent";
2021

2122
export interface DataTypeInputControlsComponentProps {
22-
suggestions?: (NodeFunction | ReferenceValue | LiteralValue)[]
23-
onSelect?: (value: NodeFunction | ReferenceValue | LiteralValue | undefined) => void
23+
suggestions?: (NodeFunction | SubFlowValue | ReferenceValue | LiteralValue)[]
24+
onSelect?: (value: NodeFunction | SubFlowValue | ReferenceValue | LiteralValue | undefined) => void
25+
showSuggestions?: boolean
2426
}
2527

2628
export const DataTypeInputControlsComponent: React.FC<DataTypeInputControlsComponentProps> = (props) => {
2729

28-
const {suggestions, onSelect} = props
30+
const {suggestions, showSuggestions = true, onSelect} = props
2931

3032
const filteredSuggestions = React.useMemo(() => {
3133
if (!suggestions) return []
32-
return suggestions.filter(suggest => suggest.__typename === "LiteralValue" || suggest.__typename === "ReferenceValue")
34+
return suggestions.filter(suggest => suggest.__typename === "LiteralValue" || suggest.__typename === "ReferenceValue" || suggest.__typename === "SubFlowValue")
3335
}, [suggestions])
3436

3537
return <ButtonGroup color={"primary"}>
36-
<Menu>
37-
<Tooltip>
38-
<TooltipTrigger asChild>
39-
<MenuTrigger asChild disabled={filteredSuggestions.length <= 0}>
40-
<Button paddingSize={"xxs"}>
41-
<IconVariable size={13}/>
42-
</Button>
43-
</MenuTrigger>
44-
</TooltipTrigger>
45-
<TooltipPortal>
46-
<TooltipContent side={"top"} sideOffset={8}>
47-
{filteredSuggestions.length <= 0 ? <Text>
48-
No suggestion available
49-
</Text> : <Text>
50-
Suggestions for this parameter
51-
</Text>}
52-
</TooltipContent>
53-
</TooltipPortal>
54-
</Tooltip>
55-
<MenuPortal>
56-
<MenuContent>
57-
{filteredSuggestions?.map((suggest, index) => {
58-
if (suggest.__typename === "LiteralValue") {
59-
return <MenuItem onSelect={() => onSelect?.(suggest)}>
60-
<Flex style={{gap: "0.35rem"}} align={"center"}>
61-
{(suggest)?.value.toString()}
62-
</Flex>
63-
</MenuItem>
64-
}
38+
{showSuggestions ? (
39+
<Menu>
40+
<Tooltip>
41+
<TooltipTrigger asChild>
42+
<MenuTrigger asChild disabled={filteredSuggestions.length <= 0}>
43+
<Button paddingSize={"xxs"}>
44+
<IconVariable size={13}/>
45+
</Button>
46+
</MenuTrigger>
47+
</TooltipTrigger>
48+
<TooltipPortal>
49+
<TooltipContent side={"top"} sideOffset={8}>
50+
{filteredSuggestions.length <= 0 ? <Text>
51+
No suggestion available
52+
</Text> : <Text>
53+
Suggestions for this parameter
54+
</Text>}
55+
</TooltipContent>
56+
</TooltipPortal>
57+
</Tooltip>
58+
<MenuPortal>
59+
<MenuContent>
60+
{filteredSuggestions?.map((suggest, index) => {
61+
if (suggest.__typename === "LiteralValue") {
62+
return <MenuItem onSelect={() => onSelect?.(suggest)}>
63+
<Flex style={{gap: "0.35rem"}} align={"center"}>
64+
{(suggest)?.value.toString()}
65+
</Flex>
66+
</MenuItem>
67+
}
6568

66-
if (suggest.__typename === "ReferenceValue") {
67-
return <MenuItem onSelect={() => onSelect?.(suggest)}>
68-
<ReferenceBadgeComponent value={suggest}/>
69-
</MenuItem>
70-
}
71-
})}
72-
</MenuContent>
73-
</MenuPortal>
74-
</Menu>
69+
if (suggest.__typename === "ReferenceValue") {
70+
return <MenuItem onSelect={() => onSelect?.(suggest)}>
71+
<ReferenceBadgeComponent value={suggest}/>
72+
</MenuItem>
73+
}
74+
75+
if (suggest.__typename === "SubFlowValue") {
76+
console.log(suggest)
77+
return <MenuItem onSelect={() => onSelect?.(suggest)}>
78+
<NodeBadgeComponent value={suggest}/>
79+
</MenuItem>
80+
}
81+
})}
82+
</MenuContent>
83+
</MenuPortal>
84+
</Menu>
85+
) : <></>}
7586
<Button paddingSize={"xxs"} onClick={(event) => {
7687
onSelect?.(undefined)
7788
event.stopPropagation()

src/packages/ce/src/datatype/components/inputs/DataTypeInputValueComponent.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,20 @@ import {ReferenceBadgeComponent} from "@edition/datatype/components/badges/Refer
88
export interface DataTypeInputValueComponentProps extends Omit<DataTypeInputComponentProps, 'schema'> {
99
children?: React.ReactNode
1010
inside?: boolean
11+
showSuggestions?: boolean
1112
}
1213

1314
export const DataTypeInputValueComponent: React.FC<DataTypeInputValueComponentProps> = (props) => {
1415

15-
const {children, inside = false, initialValue, suggestions, onChange, formValidation, ...rest} = props
16+
const {children, inside = false, initialValue, suggestions, onChange, formValidation, showSuggestions, ...rest} = props
1617

17-
return inside || initialValue?.__typename === "NodeFunction" || initialValue?.__typename === "NodeFunctionIdWrapper" || initialValue?.__typename === "ReferenceValue" ?
18+
return inside || initialValue?.__typename === "SubFlowValue" || initialValue?.__typename === "ReferenceValue" ?
1819
<InputWrapper formValidation={{...formValidation, setValue: undefined}} right={
19-
<DataTypeInputControlsComponent suggestions={suggestions} onSelect={onChange}/>
20+
<DataTypeInputControlsComponent showSuggestions={showSuggestions} suggestions={suggestions} onSelect={onChange}/>
2021
} rightType={"action"} {...rest}>
2122
<div style={{alignSelf: "center", flex: "1 1 auto"}}>
2223
{
23-
initialValue?.__typename === "NodeFunction" || initialValue?.__typename === "NodeFunctionIdWrapper" ? (
24+
initialValue?.__typename === "SubFlowValue" ? (
2425
<NodeBadgeComponent value={initialValue}/>
2526
) : initialValue?.__typename === "ReferenceValue" ? (
2627
<ReferenceBadgeComponent value={initialValue}/>

src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from "react";
22
import {DataTypeInputComponentProps} from "@edition/datatype/components/inputs/DataTypeInputComponent";
33
import {InputDescription, InputLabel, SegmentedControl, SegmentedControlItem} from "@code0-tech/pictor";
44
import {useDebouncedCallback} from "use-debounce";
5-
import {LiteralValue, NodeFunction, ReferenceValue} from "@code0-tech/sagittarius-graphql-types";
5+
import {LiteralValue, NodeFunction, ReferenceValue, SubFlowValue} from "@code0-tech/sagittarius-graphql-types";
66
import {DataTypeInputValueComponent} from "@edition/datatype/components/inputs/DataTypeInputValueComponent";
77

88
export type DataTypeBooleanInputComponentProps = DataTypeInputComponentProps
@@ -11,7 +11,7 @@ export const DataTypeBooleanInputComponent: React.FC<DataTypeBooleanInputCompone
1111

1212
const {suggestions, initialValue, title, description, formValidation, onChange} = props
1313

14-
const onChangeDebounced = useDebouncedCallback((value: string | LiteralValue | NodeFunction | ReferenceValue | undefined) => {
14+
const onChangeDebounced = useDebouncedCallback((value: string | LiteralValue | NodeFunction | SubFlowValue | ReferenceValue | undefined) => {
1515

1616
if (typeof value === "string") {
1717
const boolValue: LiteralValue | undefined = value && ["true", "false"].includes(value) ? {

src/packages/ce/src/datatype/components/inputs/json/DataTypeJSONInputComponent.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from "react"
22
import "../type/DataTypeTypeInputComponent.style.scss"
33
import {DataTypeJSONInputTreeComponent} from "./DataTypeJSONInputTreeComponent";
44
import {DataTypeInputComponentProps} from "../DataTypeInputComponent";
5-
import {LiteralValue, NodeFunction, ReferenceValue} from "@code0-tech/sagittarius-graphql-types";
5+
import {LiteralValue, NodeFunction, ReferenceValue, SubFlowValue} from "@code0-tech/sagittarius-graphql-types";
66
import {InputDescription, InputLabel, Spacing} from "@code0-tech/pictor";
77
import {
88
DataTypeJSONInputEditDialogComponent
@@ -28,7 +28,7 @@ export const DataTypeJSONInputComponent: React.FC<DataTypeJSONInputComponentProp
2828
const [editEntry, setEditEntry] = React.useState<EditableJSONEntry | undefined>(undefined)
2929
const [collapsedState, setCollapsedStateRaw] = React.useState<Record<string, boolean>>({})
3030

31-
const onChangeDebounced = useDebouncedCallback((value: LiteralValue | NodeFunction | ReferenceValue | undefined) => {
31+
const onChangeDebounced = useDebouncedCallback((value: LiteralValue | SubFlowValue | NodeFunction | ReferenceValue | undefined) => {
3232
formValidation?.setValue?.(value)
3333
onChange?.(value)
3434
}, 200)

src/packages/ce/src/datatype/components/inputs/number/DataTypeNumberInputComponent.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@ import {EditorInput, hashToColor, InputDescription, InputLabel} from "@code0-tec
44
import {StreamLanguage} from "@codemirror/language";
55
import {tags} from "@lezer/highlight";
66
import {useDebouncedCallback} from "use-debounce";
7-
import {LiteralValue, NodeFunction, NodeParameterValue, ReferenceValue} from "@code0-tech/sagittarius-graphql-types";
7+
import {
8+
LiteralValue,
9+
NodeFunction,
10+
NodeParameterValue,
11+
ReferenceValue,
12+
SubFlowValue
13+
} from "@code0-tech/sagittarius-graphql-types";
814
import {DataTypeInputControlsComponent} from "@edition/datatype/components/inputs/DataTypeInputControlsComponent";
915
import {DataTypeInputValueComponent} from "@edition/datatype/components/inputs/DataTypeInputValueComponent";
1016

@@ -15,7 +21,7 @@ export const DataTypeNumberInputComponent: React.FC<DataTypeNumberInputComponent
1521
const {formValidation, title, initialValue, description, suggestions, onChange} = props
1622

1723
const defaultValue: NodeParameterValue | NodeFunction | undefined = React.useMemo(() => initialValue ?? undefined, [initialValue])
18-
const onChangeDebounced = useDebouncedCallback((value: string | LiteralValue | NodeFunction | ReferenceValue | undefined) => {
24+
const onChangeDebounced = useDebouncedCallback((value: string | LiteralValue | SubFlowValue | NodeFunction | ReferenceValue | undefined) => {
1925

2026
if (typeof value === "string") {
2127
console.log(value)

0 commit comments

Comments
 (0)