6654 serverless functions add a deploy button disable deploy when autosave (#6715)
- improvements on serverless function behavior (autosave performances, deploy on execution only) - add versioning to serverless functions - add a publish endpoint to create a new version of a serverless function - add deploy and reset to lastVersion button in the settings section: <img width="736" alt="image" src="https://github.com/user-attachments/assets/2001f8d2-07a4-4f79-84dd-ec74b6f301d3">
This commit is contained in:
@ -6,6 +6,7 @@ import { SettingsServerlessFunctionTestTabEffect } from '@/settings/serverless-f
|
||||
import { useExecuteOneServerlessFunction } from '@/settings/serverless-functions/hooks/useExecuteOneServerlessFunction';
|
||||
import { useServerlessFunctionUpdateFormState } from '@/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState';
|
||||
import { useUpdateOneServerlessFunction } from '@/settings/serverless-functions/hooks/useUpdateOneServerlessFunction';
|
||||
import { usePublishOneServerlessFunction } from '@/settings/serverless-functions/hooks/usePublishOneServerlessFunction';
|
||||
import { settingsServerlessFunctionInputState } from '@/settings/serverless-functions/states/settingsServerlessFunctionInputState';
|
||||
import { settingsServerlessFunctionOutputState } from '@/settings/serverless-functions/states/settingsServerlessFunctionOutputState';
|
||||
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
||||
@ -18,7 +19,10 @@ import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
import { IconCode, IconFunction, IconSettings, IconTestPipe } from 'twenty-ui';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
import { useGetOneServerlessFunctionSourceCode } from '@/settings/serverless-functions/hooks/useGetOneServerlessFunctionSourceCode';
|
||||
import { useState } from 'react';
|
||||
|
||||
const TAB_LIST_COMPONENT_ID = 'serverless-function-detail';
|
||||
|
||||
@ -29,10 +33,16 @@ export const SettingsServerlessFunctionDetail = () => {
|
||||
TAB_LIST_COMPONENT_ID,
|
||||
);
|
||||
const activeTabId = useRecoilValue(activeTabIdState);
|
||||
const [isCodeValid, setIsCodeValid] = useState(true);
|
||||
const { executeOneServerlessFunction } = useExecuteOneServerlessFunction();
|
||||
const { updateOneServerlessFunction } = useUpdateOneServerlessFunction();
|
||||
const { publishOneServerlessFunction } = usePublishOneServerlessFunction();
|
||||
const [formValues, setFormValues] =
|
||||
useServerlessFunctionUpdateFormState(serverlessFunctionId);
|
||||
const { code: latestVersionCode } = useGetOneServerlessFunctionSourceCode({
|
||||
id: serverlessFunctionId,
|
||||
version: 'latest',
|
||||
});
|
||||
const setSettingsServerlessFunctionOutput = useSetRecoilState(
|
||||
settingsServerlessFunctionOutputState,
|
||||
);
|
||||
@ -70,13 +80,56 @@ export const SettingsServerlessFunctionDetail = () => {
|
||||
};
|
||||
};
|
||||
|
||||
const handleExecute = async () => {
|
||||
await handleSave();
|
||||
const resetDisabled =
|
||||
!isDefined(latestVersionCode) || latestVersionCode === formValues.code;
|
||||
const publishDisabled = !isCodeValid || latestVersionCode === formValues.code;
|
||||
|
||||
const handleReset = async () => {
|
||||
try {
|
||||
const result = await executeOneServerlessFunction(
|
||||
serverlessFunctionId,
|
||||
JSON.parse(settingsServerlessFunctionInput),
|
||||
const newState = {
|
||||
code: latestVersionCode || '',
|
||||
};
|
||||
setFormValues((prevState) => ({
|
||||
...prevState,
|
||||
...newState,
|
||||
}));
|
||||
await handleSave();
|
||||
} catch (err) {
|
||||
enqueueSnackBar(
|
||||
(err as Error)?.message || 'An error occurred while reset function',
|
||||
{
|
||||
variant: SnackBarVariant.Error,
|
||||
},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handlePublish = async () => {
|
||||
try {
|
||||
await publishOneServerlessFunction({
|
||||
id: serverlessFunctionId,
|
||||
});
|
||||
enqueueSnackBar(`New function version has been published`, {
|
||||
variant: SnackBarVariant.Success,
|
||||
});
|
||||
} catch (err) {
|
||||
enqueueSnackBar(
|
||||
(err as Error)?.message ||
|
||||
'An error occurred while publishing new version',
|
||||
{
|
||||
variant: SnackBarVariant.Error,
|
||||
},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleExecute = async () => {
|
||||
try {
|
||||
const result = await executeOneServerlessFunction({
|
||||
id: serverlessFunctionId,
|
||||
payload: JSON.parse(settingsServerlessFunctionInput),
|
||||
version: 'draft',
|
||||
});
|
||||
setSettingsServerlessFunctionOutput({
|
||||
data: result?.data?.executeOneServerlessFunction?.data
|
||||
? JSON.stringify(
|
||||
@ -119,7 +172,12 @@ export const SettingsServerlessFunctionDetail = () => {
|
||||
<SettingsServerlessFunctionCodeEditorTab
|
||||
formValues={formValues}
|
||||
handleExecute={handleExecute}
|
||||
handlePublish={handlePublish}
|
||||
handleReset={handleReset}
|
||||
resetDisabled={resetDisabled}
|
||||
publishDisabled={publishDisabled}
|
||||
onChange={onChange}
|
||||
setIsCodeValid={setIsCodeValid}
|
||||
/>
|
||||
);
|
||||
case 'test':
|
||||
|
||||
Reference in New Issue
Block a user