Skip to content

Commit 2cfa852

Browse files
authored
Merge pull request #143 from code0-tech/feat/#142
Performance is really bad within suggestion menu
2 parents 015a8ef + 6a29b4b commit 2cfa852

12 files changed

Lines changed: 50 additions & 93 deletions

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

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import {
2424
DataTypeJSONInputEditDialogComponent
2525
} from "@edition/datatype/components/inputs/json/DataTypeJSONInputEditDialogComponent";
2626
import {FlowService} from "@edition/flow/services/Flow.service";
27-
import {FunctionService} from "@edition/function/services/Function.service";
2827
import {useValue} from "@edition/datatype/hooks/DataType.value.hook";
2928

3029
export interface EditableJSONEntry {
@@ -42,10 +41,9 @@ export const DataTypeJSONInputComponent: React.FC<DataTypeJSONInputComponentProp
4241

4342
const flowService = useService(FlowService)
4443
const flowStore = useStore(FlowService)
45-
const functionService = useService(FunctionService)
46-
const functionStore = useStore(FunctionService)
4744

4845
const initialNullValue = useValue(flowId, nodeId, parameterIndex)
46+
const suggestions = useSuggestions(flowId, nodeId, parameterIndex)
4947

5048
const node = React.useMemo(
5149
() => flowService.getNodeById(flowId, nodeId),
@@ -54,25 +52,13 @@ export const DataTypeJSONInputComponent: React.FC<DataTypeJSONInputComponentProp
5452

5553
const parameter = node?.parameters?.nodes?.[parameterIndex]
5654

57-
const functionDefinition = React.useMemo(
58-
() => functionService.getById(node?.functionDefinition?.id!),
59-
[functionStore, node]
60-
)
61-
62-
const parameterDefinition = React.useMemo(
63-
() => functionDefinition?.parameterDefinitions?.nodes?.find(pd => pd?.id === parameter?.parameterDefinition?.id),
64-
[functionDefinition, parameter]
65-
)
66-
6755
const initialValue: NodeParameterValue | null = React.useMemo(() => {
6856
if (!parameter?.value || (parameter?.value?.__typename === "LiteralValue" && parameter.value.value == null)) {
6957
return initialNullValue
7058
}
7159
return parameter?.value
7260
}, [initialNullValue])
7361

74-
const suggestions = useSuggestions(flowId, nodeId, parameterIndex)
75-
7662
const [value, setValue] = React.useState<NodeParameterValue | NodeFunction | null>(initialValue)
7763
const [editDialogOpen, setEditDialogOpen] = React.useState(false)
7864
const [editEntry, setEditEntry] = React.useState<EditableJSONEntry | null>(null)

src/packages/ce/src/datatype/hooks/DataType.value.hook.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {FunctionService} from "@edition/function/services/Function.service";
44
import {FlowService} from "@edition/flow/services/Flow.service";
55
import {DatatypeService} from "@edition/datatype/services/Datatype.service";
66
import {useNodeTypeExtractionAction, useValueExtractionAction} from "@edition/flow/components/FlowWorkerProvider";
7-
import React, {startTransition} from "react";
7+
import React from "react";
88

99
export const useValue = (
1010
flowId: Flow['id'],
@@ -47,9 +47,7 @@ export const useValue = (
4747
dataTypes: dataTypes,
4848
functions: functions
4949
}).then(value => {
50-
startTransition(() => {
51-
setTypes(value)
52-
})
50+
setTypes(value)
5351
})
5452
}, 200);
5553

@@ -63,9 +61,7 @@ export const useValue = (
6361
type: types?.parameters?.[parameterIndex ?? 0],
6462
dataTypes: dataTypes
6563
}).then(value => {
66-
startTransition(() => {
67-
setValue(value)
68-
})
64+
setValue(value)
6965
})
7066
}, 200);
7167

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, {startTransition} from "react"
1+
import React from "react"
22
import type {Flow} from "@code0-tech/sagittarius-graphql-types"
33
import {useService, useStore} from "@code0-tech/pictor";
44
import {FunctionService} from "@edition/function/services/Function.service";
@@ -7,11 +7,7 @@ import {DatatypeService} from "@edition/datatype/services/Datatype.service";
77
import {ValidationResult} from "@core/util/inspection";
88
import {useFlowValidationAction} from "@edition/flow/components/FlowWorkerProvider";
99

10-
declare global {
11-
interface Window {
12-
lastValidatedFlows?: Record<string, { lastValidated: string, validation: ValidationResult[] }>;
13-
}
14-
}
10+
const globalPendingValidations = new Map<string, Promise<ValidationResult[]>>()
1511

1612
export const useFlowValidation = (
1713
flowId: Flow['id']
@@ -31,40 +27,37 @@ export const useFlowValidation = (
3127
() => flowService.getById(flowId),
3228
[flowStore, flowId, flowService]
3329
)
34-
3530
const functions = React.useMemo(() => functionService.values(), [functionStore]);
3631
const dataTypes = React.useMemo(() => dataTypeService.values(), [dataTypeStore]);
3732

3833
React.useEffect(() => {
3934
if (!flow) return;
4035

41-
// Skip if already validated for this version
42-
if (flow.editedAt && window.lastValidatedFlows?.[flowId as string]?.lastValidated === flow.editedAt) {
43-
setValidationResult(window.lastValidatedFlows?.[flowId as string].validation!)
44-
return;
45-
}
46-
4736
const timeout = setTimeout(() => {
48-
execute({
37+
const key = flowId as string;
38+
39+
if (globalPendingValidations.has(key)) {
40+
globalPendingValidations.get(key)!.then(value => {
41+
setValidationResult(value as ValidationResult[])
42+
});
43+
return;
44+
}
45+
46+
const promise = execute({
4947
flow,
5048
functions,
5149
dataTypes
5250
}).then(value => {
53-
startTransition(() => {
54-
setValidationResult(value as ValidationResult[])
55-
window.lastValidatedFlows = {
56-
...window.lastValidatedFlows,
57-
[flowId as string]: {
58-
lastValidated: flow.editedAt!,
59-
validation: value as ValidationResult[]
60-
}
61-
}
62-
})
51+
setValidationResult(value as ValidationResult[])
52+
globalPendingValidations.delete(key);
53+
return value;
6354
});
55+
56+
globalPendingValidations.set(key, promise as Promise<ValidationResult[]>);
6457
}, 200);
6558

6659
return () => clearTimeout(timeout);
67-
}, [flow, functions, dataTypes, flowStore])
60+
}, [flow?.editedAt, functions.length, dataTypes.length])
6861

6962
return validationResult
7063
}

src/packages/ce/src/flow/views/FlowFolderView.tsx

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ export const FlowFolderView: React.FC = () => {
3737
const projectIndex = params.projectId as any as number
3838
const flowIndex = params.flowId as any as number
3939
const flowId: Flow['id'] = `gid://sagittarius/Flow/${flowIndex}`
40-
41-
const [, startTransition] = React.useTransition()
4240
const ref = React.useRef<FlowFolderComponentHandle>(null)
4341

4442
const [createDialogOpen, setCreateDialogOpen] = React.useState(false)
@@ -53,19 +51,17 @@ export const FlowFolderView: React.FC = () => {
5351

5452
const deleteFlow = React.useCallback((flow: Flow) => {
5553
if (!flow?.id) return
56-
startTransition(() => {
57-
flowService.flowDelete({
58-
flowId: flow.id!
59-
}).then(payload => {
60-
if ((payload?.errors?.length ?? 0) <= 0) {
61-
toast({
62-
title: "The flow was successfully deleted.",
63-
color: "success",
64-
dismissible: true,
65-
})
66-
router.push(`/namespace/${namespaceIndex}/project/${projectIndex}/flow`)
67-
}
68-
})
54+
flowService.flowDelete({
55+
flowId: flow.id!
56+
}).then(payload => {
57+
if ((payload?.errors?.length ?? 0) <= 0) {
58+
toast({
59+
title: "The flow was successfully deleted.",
60+
color: "success",
61+
dismissible: true,
62+
})
63+
router.push(`/namespace/${namespaceIndex}/project/${projectIndex}/flow`)
64+
}
6965
})
7066
}, [flowService])
7167

src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react";
1+
import React, {startTransition} from "react";
22
import {Flex, InputSyntaxSegment, useForm, useService, useStore} from "@code0-tech/pictor";
33
import {
44
Flow,
@@ -29,12 +29,10 @@ export const FunctionFileDefaultComponent: React.FC<FunctionFileDefaultComponent
2929
const functionService = useService(FunctionService)
3030
const functionStore = useStore(FunctionService)
3131
const flowService = useService(FlowService)
32-
const flowStore = useStore(FlowService)
3332
const fileTabsService = useService(FileTabsService)
3433
const validation = useFlowValidation(flowId)
3534

3635
const changedParameters = React.useRef<Set<number>>(new Set())
37-
const [, startTransition] = React.useTransition()
3836

3937
const definition = React.useMemo(() => {
4038
return functionService.getById(node.functionDefinition?.id!!)
@@ -53,9 +51,9 @@ export const FunctionFileDefaultComponent: React.FC<FunctionFileDefaultComponent
5351
const values: Record<string, any> = {}
5452
node.parameters?.nodes?.forEach((parameter, index) => {
5553
values[index] = (_: any) => {
56-
const validationForParameter = validation?.find(v => v.parameterIndex === index && v.nodeId === node.id)
54+
const validationForParameter = validation?.find(v => v?.parameterIndex === index && v?.nodeId === node.id)
5755
if (validationForParameter) {
58-
return validationForParameter.message?.[0]?.content ?? "Invalid value"
56+
return validationForParameter?.message?.[0]?.content ?? "Invalid value"
5957
}
6058
return null
6159
}
@@ -111,7 +109,7 @@ export const FunctionFileDefaultComponent: React.FC<FunctionFileDefaultComponent
111109
}
112110
changedParameters.current.clear()
113111
})
114-
}, [flowStore])
112+
}, [flowService])
115113

116114
const [inputs, validate] = useForm<Record<number, InputSyntaxSegment[]>>({
117115
initialValues: initialValues,

src/packages/ce/src/function/components/files/FunctionFilesComponent.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,7 @@ export const FunctionFilesComponent: React.FC<FunctionFilesComponentProps> = (pr
160160
</FileTabsList>}>
161161
<>
162162
{fileTabsService.values().map((tab: FileTabsView) => (
163-
<FileTabsContent forceMount
164-
display={tab.active ? "block" : "none"}
163+
<FileTabsContent display={tab.active ? "block" : "none"}
165164
key={`content-${tab.id}`}
166165
value={tab.id!}>
167166
{tab.content}

src/packages/ce/src/function/components/suggestion/FunctionSuggestionComponent.view.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ export enum FunctionSuggestionType {
1414
}
1515

1616
export interface FunctionSuggestion {
17-
1817
displayText: string[]
1918
path: number[]
2019
value: LiteralValue | ReferenceValue | NodeFunction

src/packages/ce/src/function/components/suggestion/FunctionSuggestionMenuComponent.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import {toInputSuggestions} from "./FunctionSuggestionMenuComponent.util";
44
import {FunctionSuggestionSearchBarComponent} from "./FunctionSuggestionSearchBarComponent";
55
import {
66
Card,
7-
InputSuggestionMenuContent, InputSuggestionMenuContentItems,
7+
InputSuggestionMenuContent,
8+
InputSuggestionMenuContentItems,
89
InputSuggestionMenuContentItemsHandle,
910
Menu,
1011
MenuPortal,
@@ -19,10 +20,7 @@ export interface FunctionSuggestionMenuComponentProps {
1920

2021
export const FunctionSuggestionMenuComponent: React.FC<FunctionSuggestionMenuComponentProps> = (props) => {
2122

22-
const {
23-
suggestions = [], triggerContent, onSuggestionSelect = () => {
24-
}
25-
} = props
23+
const {suggestions = [], triggerContent, onSuggestionSelect = () => null} = props
2624

2725
const menuRef = React.useRef<InputSuggestionMenuContentItemsHandle | null>(null); // Ref to suggestion list
2826
const [stateSuggestions, setStateSuggestions] = React.useState(suggestions)

src/packages/ce/src/function/hooks/FunctionNodeSuggestions.hook.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
import {useService, useStore} from "@code0-tech/pictor";
66
import {FunctionService} from "@edition/function/services/Function.service";
77
import {DatatypeService} from "@edition/datatype/services/Datatype.service";
8-
import React, {startTransition} from "react";
8+
import React from "react";
99
import {useNodeSuggestionsAction} from "@edition/flow/components/FlowWorkerProvider";
1010
import {icon, IconString} from "@core/util/icons";
1111
import {FALLBACK_FUNCTION_NAME} from "@core/util/fallback-translations";
@@ -33,9 +33,7 @@ export const useNodeSuggestions = (
3333
functions,
3434
dataTypes
3535
}).then(value => {
36-
startTransition(() => {
37-
setSuggestions(value as any[])
38-
})
36+
setSuggestions(value as any[])
3937
})
4038
}, 200);
4139

src/packages/ce/src/function/hooks/FunctionReferenceSuggestions.hook.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {useService, useStore} from "@code0-tech/pictor";
77
import {FunctionService} from "@edition/function/services/Function.service";
88
import {DatatypeService} from "@edition/datatype/services/Datatype.service";
99
import {FlowService} from "@edition/flow/services/Flow.service";
10-
import React, {startTransition} from "react";
10+
import React from "react";
1111
import {useReferenceSuggestionsAction} from "@edition/flow/components/FlowWorkerProvider";
1212

1313
export const useReferenceSuggestions = (
@@ -44,9 +44,7 @@ export const useReferenceSuggestions = (
4444
functions,
4545
dataTypes
4646
}).then(value => {
47-
startTransition(() => {
48-
setSuggestions(value as any[])
49-
})
47+
setSuggestions(value as any[])
5048
})
5149
}, 200);
5250

0 commit comments

Comments
 (0)