6653 serverless functions store and use environment variables in serverless function scripts (#7390)

![image](https://github.com/user-attachments/assets/a15bd4c1-3db4-4466-b748-06bdf3874354)

![image](https://github.com/user-attachments/assets/71242dfb-956b-43ed-9704-87cb0dfbc98d)
This commit is contained in:
martmull
2024-10-03 13:56:17 +02:00
committed by GitHub
parent 3cd24d542b
commit 62fe1d0e88
39 changed files with 815 additions and 513 deletions

View File

@ -24,6 +24,7 @@ import { useRecoilValue, useSetRecoilState } from 'recoil';
import { IconCode, IconFunction, IconSettings, IconTestPipe } from 'twenty-ui';
import { usePreventOverlapCallback } from '~/hooks/usePreventOverlapCallback';
import { isDefined } from '~/utils/isDefined';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
const TAB_LIST_COMPONENT_ID = 'serverless-function-detail';
@ -81,14 +82,24 @@ export const SettingsServerlessFunctionDetail = () => {
};
};
const onCodeChange = async (filePath: string, value: string) => {
setFormValues((prevState) => ({
...prevState,
code: { ...prevState.code, [filePath]: value },
}));
await handleSave();
};
const resetDisabled =
!isDefined(latestVersionCode) || latestVersionCode === formValues.code;
const publishDisabled = !isCodeValid || latestVersionCode === formValues.code;
!isDefined(latestVersionCode) ||
isDeeplyEqual(latestVersionCode, formValues.code);
const publishDisabled =
!isCodeValid || isDeeplyEqual(latestVersionCode, formValues.code);
const handleReset = async () => {
try {
const newState = {
code: latestVersionCode || '',
code: latestVersionCode || {},
};
setFormValues((prevState) => ({
...prevState,
@ -166,18 +177,30 @@ export const SettingsServerlessFunctionDetail = () => {
{ id: 'settings', title: 'Settings', Icon: IconSettings },
];
const files = formValues.code
? Object.keys(formValues.code)
.map((key) => {
return {
path: key,
language: key === '.env' ? 'ini' : 'typescript',
content: formValues.code?.[key] || '',
};
})
.reverse()
: [];
const renderActiveTabContent = () => {
switch (activeTabId) {
case 'editor':
return (
<SettingsServerlessFunctionCodeEditorTab
formValues={formValues}
files={files}
handleExecute={handleExecute}
handlePublish={handlePublish}
handleReset={handleReset}
resetDisabled={resetDisabled}
publishDisabled={publishDisabled}
onChange={onChange}
onChange={onCodeChange}
setIsCodeValid={setIsCodeValid}
/>
);

View File

@ -9,7 +9,6 @@ import { ServerlessFunctionNewFormValues } from '@/settings/serverless-functions
import { SettingsServerlessFunctionHotkeyScope } from '@/settings/serverless-functions/types/SettingsServerlessFunctionHotKeyScope';
import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
import { SettingsPath } from '@/types/SettingsPath';
import { DEFAULT_CODE } from '@/ui/input/code-editor/components/CodeEditor';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useState } from 'react';
import { Key } from 'ts-key-enum';
@ -31,7 +30,6 @@ export const SettingsServerlessFunctionsNew = () => {
const newServerlessFunction = await createOneServerlessFunction({
name: formValues.name,
description: formValues.description,
code: DEFAULT_CODE,
});
if (!isDefined(newServerlessFunction?.data)) {

View File

@ -1,4 +1,3 @@
import { DEFAULT_CODE } from '@/ui/input/code-editor/components/CodeEditor';
import { Meta, StoryObj } from '@storybook/react';
import { within } from '@storybook/test';
import { graphql, http, HttpResponse } from 'msw';
@ -38,7 +37,6 @@ const meta: Meta<PageDecoratorArgs> = {
description: '',
syncStatus: 'READY',
runtime: 'nodejs18.x',
sourceCodeHash: '42d2734b3dc8a7b45a16803ed7f417bc',
updatedAt: '2024-02-24T10:23:10.673Z',
createdAt: '2024-02-24T10:23:10.673Z',
},
@ -46,7 +44,7 @@ const meta: Meta<PageDecoratorArgs> = {
});
}),
http.get(getImageAbsoluteURI(SOURCE_CODE_FULL_PATH) || '', () => {
return HttpResponse.text(DEFAULT_CODE);
return HttpResponse.text('export const handler = () => {}');
}),
],
},