Add console logs to code step (#10786)

Works for local and lambda drivers

## After

![image](https://github.com/user-attachments/assets/ec082cf6-4159-4a15-99b6-243c73a13773)

![image](https://github.com/user-attachments/assets/f42e3f43-5ea4-4167-b4b5-9a17826fd224)
This commit is contained in:
martmull
2025-03-12 10:40:59 +01:00
committed by GitHub
parent 4d0450069c
commit 4036933c84
11 changed files with 189 additions and 9 deletions

View File

@ -36,7 +36,7 @@ const documents = {
"\n fragment ServerlessFunctionFields on ServerlessFunction {\n id\n name\n description\n runtime\n timeoutSeconds\n syncStatus\n latestVersion\n latestVersionInputSchema\n publishedVersions\n createdAt\n updatedAt\n }\n": types.ServerlessFunctionFieldsFragmentDoc,
"\n \n mutation CreateOneServerlessFunctionItem(\n $input: CreateServerlessFunctionInput!\n ) {\n createOneServerlessFunction(input: $input) {\n ...ServerlessFunctionFields\n }\n }\n": types.CreateOneServerlessFunctionItemDocument,
"\n \n mutation DeleteOneServerlessFunction($input: ServerlessFunctionIdInput!) {\n deleteOneServerlessFunction(input: $input) {\n ...ServerlessFunctionFields\n }\n }\n": types.DeleteOneServerlessFunctionDocument,
"\n mutation ExecuteOneServerlessFunction(\n $input: ExecuteServerlessFunctionInput!\n ) {\n executeOneServerlessFunction(input: $input) {\n data\n duration\n status\n error\n }\n }\n": types.ExecuteOneServerlessFunctionDocument,
"\n mutation ExecuteOneServerlessFunction(\n $input: ExecuteServerlessFunctionInput!\n ) {\n executeOneServerlessFunction(input: $input) {\n data\n logs\n duration\n status\n error\n }\n }\n": types.ExecuteOneServerlessFunctionDocument,
"\n \n mutation PublishOneServerlessFunction(\n $input: PublishServerlessFunctionInput!\n ) {\n publishServerlessFunction(input: $input) {\n ...ServerlessFunctionFields\n }\n }\n": types.PublishOneServerlessFunctionDocument,
"\n \n mutation UpdateOneServerlessFunction($input: UpdateServerlessFunctionInput!) {\n updateOneServerlessFunction(input: $input) {\n ...ServerlessFunctionFields\n }\n }\n": types.UpdateOneServerlessFunctionDocument,
"\n query FindManyAvailablePackages($input: ServerlessFunctionIdInput!) {\n getAvailablePackages(input: $input)\n }\n": types.FindManyAvailablePackagesDocument,
@ -154,7 +154,7 @@ export function graphql(source: "\n \n mutation DeleteOneServerlessFunction($i
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n mutation ExecuteOneServerlessFunction(\n $input: ExecuteServerlessFunctionInput!\n ) {\n executeOneServerlessFunction(input: $input) {\n data\n duration\n status\n error\n }\n }\n"): (typeof documents)["\n mutation ExecuteOneServerlessFunction(\n $input: ExecuteServerlessFunctionInput!\n ) {\n executeOneServerlessFunction(input: $input) {\n data\n duration\n status\n error\n }\n }\n"];
export function graphql(source: "\n mutation ExecuteOneServerlessFunction(\n $input: ExecuteServerlessFunctionInput!\n ) {\n executeOneServerlessFunction(input: $input) {\n data\n logs\n duration\n status\n error\n }\n }\n"): (typeof documents)["\n mutation ExecuteOneServerlessFunction(\n $input: ExecuteServerlessFunctionInput!\n ) {\n executeOneServerlessFunction(input: $input) {\n data\n logs\n duration\n status\n error\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/

File diff suppressed because one or more lines are too long

View File

@ -45,6 +45,7 @@ export const useTestServerlessFunction = ({
4,
)
: undefined,
logs: result?.data?.executeOneServerlessFunction?.logs || '',
duration: result?.data?.executeOneServerlessFunction?.duration,
status: result?.data?.executeOneServerlessFunction?.status,
error: result?.data?.executeOneServerlessFunction?.error

View File

@ -6,6 +6,7 @@ export const EXECUTE_ONE_SERVERLESS_FUNCTION = gql`
) {
executeOneServerlessFunction(input: $input) {
data
logs
duration
status
error

View File

@ -14,6 +14,7 @@ export type TextAreaProps = {
label?: string;
disabled?: boolean;
minRows?: number;
maxRows?: number;
onChange?: (value: string) => void;
placeholder?: string;
value?: string;
@ -73,12 +74,13 @@ export const TextArea = ({
disabled,
placeholder,
minRows = 1,
maxRows = MAX_ROWS,
value = '',
className,
onChange,
onBlur,
}: TextAreaProps) => {
const computedMinRows = Math.min(minRows, MAX_ROWS);
const computedMinRows = Math.min(minRows, maxRows);
const inputId = useId();
@ -103,7 +105,7 @@ export const TextArea = ({
<StyledTextArea
id={inputId}
placeholder={placeholder}
maxRows={MAX_ROWS}
maxRows={maxRows}
minRows={computedMinRows}
value={value}
onChange={(event) =>

View File

@ -5,6 +5,7 @@ export type ServerlessFunctionTestData = {
input: { [field: string]: any };
output: {
data?: string;
logs: string;
duration?: number;
status?: ServerlessFunctionExecutionStatus;
error?: string;
@ -15,6 +16,7 @@ export type ServerlessFunctionTestData = {
export const DEFAULT_OUTPUT_VALUE = {
data: 'Enter an input above then press "Test"',
logs: '',
status: ServerlessFunctionExecutionStatus.IDLE,
};

View File

@ -37,6 +37,7 @@ import { useRecoilState, useRecoilValue } from 'recoil';
import { isDefined } from 'twenty-shared';
import { CodeEditor, IconCode, IconPlayerPlay, useIcons } from 'twenty-ui';
import { useDebouncedCallback } from 'use-debounce';
import { TextArea } from '@/ui/input/components/TextArea';
const StyledContainer = styled.div`
display: flex;
@ -340,6 +341,16 @@ export const WorkflowEditActionFormServerlessFunction = ({
isTesting={isTesting}
/>
</StyledCodeEditorContainer>
<StyledCodeEditorContainer>
<InputLabel>Logs</InputLabel>
<TextArea
value={
isTesting ? '' : serverlessFunctionTestData.output.logs
}
maxRows={20}
disabled
/>
</StyledCodeEditorContainer>
</>
)}
</WorkflowStepBody>