Files
twenty/packages/twenty-front/src/modules/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTestTab.tsx
Baptiste Devessier 6521d19238 Use JSON visualizer for JSON fields (#11428)
- Updates on the JSON field input
  - Previously, we were editing json fields in a textarea 
- Now, we display a JSON visualizer and the user can click on an Edit
button to edit the JSON in Monaco
- The JSON field input has a special behavior for workflow run output.
We want the error to be displayed first in the visualizer. Displaying
the error in red was optional but makes the output clearer in the
context of a workflow run record board.
- Made the code editor transparent in the json field input
- Ensure workflow run's output is not considered readonly in
`packages/twenty-front/src/modules/object-record/record-field/utils/isFieldValueReadOnly.ts`;
we want the json visualizer to always be displayed in this specific case

## Demo

### Failed Workflow Run


https://github.com/user-attachments/assets/7a438d11-53fb-4425-a982-25bbea4ee7a8

### Any JSON field in the record table


https://github.com/user-attachments/assets/b5591abe-3483-4473-bd87-062a45e653e3

Closes https://github.com/twentyhq/core-team-issues/issues/539
2025-04-08 16:18:36 +00:00

92 lines
2.9 KiB
TypeScript

import { ServerlessFunctionExecutionResult } from '@/serverless-functions/components/ServerlessFunctionExecutionResult';
import { SettingsServerlessFunctionHotkeyScope } from '@/settings/serverless-functions/types/SettingsServerlessFunctionHotKeyScope';
import { SettingsPath } from '@/types/SettingsPath';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { serverlessFunctionTestDataFamilyState } from '@/workflow/states/serverlessFunctionTestDataFamilyState';
import styled from '@emotion/styled';
import { useRecoilState } from 'recoil';
import { Key } from 'ts-key-enum';
import { useHotkeyScopeOnMount } from '~/hooks/useHotkeyScopeOnMount';
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
import { Button, CodeEditor, CoreEditorHeader } from 'twenty-ui/input';
import { H2Title, IconPlayerPlay } from 'twenty-ui/display';
import { Section } from 'twenty-ui/layout';
const StyledInputsContainer = styled.div`
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(4)};
`;
const StyledCodeEditorContainer = styled.div`
display: flex;
flex-direction: column;
`;
export const SettingsServerlessFunctionTestTab = ({
handleExecute,
serverlessFunctionId,
}: {
handleExecute: () => void;
serverlessFunctionId: string;
}) => {
const [serverlessFunctionTestData, setServerlessFunctionTestData] =
useRecoilState(serverlessFunctionTestDataFamilyState(serverlessFunctionId));
const onChange = (newInput: string) => {
setServerlessFunctionTestData((prev) => ({
...prev,
input: JSON.parse(newInput),
}));
};
const navigate = useNavigateSettings();
useHotkeyScopeOnMount(
SettingsServerlessFunctionHotkeyScope.ServerlessFunctionTestTab,
);
useScopedHotkeys(
[Key.Escape],
() => {
navigate(SettingsPath.ServerlessFunctions);
},
SettingsServerlessFunctionHotkeyScope.ServerlessFunctionTestTab,
);
return (
<Section>
<H2Title
title="Test your function"
description='Insert a JSON input, then press "Run" to test your function.'
/>
<StyledInputsContainer>
<StyledCodeEditorContainer>
<CoreEditorHeader
title={'Input'}
rightNodes={[
<Button
title="Run Function"
variant="primary"
accent="blue"
size="small"
Icon={IconPlayerPlay}
onClick={handleExecute}
/>,
]}
/>
<CodeEditor
value={JSON.stringify(serverlessFunctionTestData.input, null, 4)}
language="json"
height={200}
onChange={onChange}
variant="with-header"
/>
</StyledCodeEditorContainer>
<ServerlessFunctionExecutionResult
serverlessFunctionTestData={serverlessFunctionTestData}
/>
</StyledInputsContainer>
</Section>
);
};