mirror of
				https://github.com/lingble/twenty.git
				synced 2025-10-30 20:27:55 +00:00 
			
		
		
		
	Enable workflow testing + fix header (#8512)
- clean execution header - enable test on workflows + add snack bar - display snack bar error if workflow cannot be tested Behaviour still need to be validated by @Bonapara <img width="880" alt="Capture d’écran 2024-11-15 à 12 16 36" src="https://github.com/user-attachments/assets/1dab0c3b-157c-449f-aee7-4c8cf2e369a6"> <img width="880" alt="Capture d’écran 2024-11-15 à 12 16 48" src="https://github.com/user-attachments/assets/16279611-0a58-4fe6-b117-0192714a6d5c">
This commit is contained in:
		| @@ -34,7 +34,9 @@ export const WorkflowRunActionEffect = () => { | |||||||
|         position: index, |         position: index, | ||||||
|         Icon: IconSettingsAutomation, |         Icon: IconSettingsAutomation, | ||||||
|         onClick: async () => { |         onClick: async () => { | ||||||
|           await runWorkflowVersion(activeWorkflowVersion.id); |           await runWorkflowVersion({ | ||||||
|  |             workflowVersionId: activeWorkflowVersion.id, | ||||||
|  |           }); | ||||||
|  |  | ||||||
|           enqueueSnackBar('', { |           enqueueSnackBar('', { | ||||||
|             variant: SnackBarVariant.Success, |             variant: SnackBarVariant.Success, | ||||||
|   | |||||||
| @@ -65,7 +65,10 @@ export const WorkflowRunRecordActionEffect = ({ | |||||||
|             return; |             return; | ||||||
|           } |           } | ||||||
|  |  | ||||||
|           await runWorkflowVersion(activeWorkflowVersion.id, selectedRecord); |           await runWorkflowVersion({ | ||||||
|  |             workflowVersionId: activeWorkflowVersion.id, | ||||||
|  |             payload: selectedRecord, | ||||||
|  |           }); | ||||||
|  |  | ||||||
|           enqueueSnackBar('', { |           enqueueSnackBar('', { | ||||||
|             variant: SnackBarVariant.Success, |             variant: SnackBarVariant.Success, | ||||||
|   | |||||||
| @@ -15,6 +15,7 @@ import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; | |||||||
| import { SHOW_PAGE_ADD_BUTTON_DROPDOWN_ID } from '@/ui/layout/show-page/constants/ShowPageAddButtonDropdownId'; | import { SHOW_PAGE_ADD_BUTTON_DROPDOWN_ID } from '@/ui/layout/show-page/constants/ShowPageAddButtonDropdownId'; | ||||||
|  |  | ||||||
| import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; | import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; | ||||||
|  | import { isWorkflowSubObjectMetadata } from '@/object-metadata/utils/isWorkflowSubObjectMetadata'; | ||||||
| import { Dropdown } from '../../dropdown/components/Dropdown'; | import { Dropdown } from '../../dropdown/components/Dropdown'; | ||||||
| import { DropdownMenu } from '../../dropdown/components/DropdownMenu'; | import { DropdownMenu } from '../../dropdown/components/DropdownMenu'; | ||||||
|  |  | ||||||
| @@ -54,7 +55,8 @@ export const ShowPageAddButton = ({ | |||||||
|     activityTargetObject.targetObjectNameSingular === |     activityTargetObject.targetObjectNameSingular === | ||||||
|       CoreObjectNameSingular.Task || |       CoreObjectNameSingular.Task || | ||||||
|     activityTargetObject.targetObjectNameSingular === |     activityTargetObject.targetObjectNameSingular === | ||||||
|       CoreObjectNameSingular.Note |       CoreObjectNameSingular.Note || | ||||||
|  |     isWorkflowSubObjectMetadata(activityTargetObject.targetObjectNameSingular) | ||||||
|   ) { |   ) { | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -15,6 +15,7 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop | |||||||
| import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; | import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; | ||||||
| import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState'; | import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState'; | ||||||
|  |  | ||||||
|  | import { isObjectMetadataReadOnly } from '@/object-metadata/utils/isObjectMetadataReadOnly'; | ||||||
| import { useDestroyOneRecord } from '@/object-record/hooks/useDestroyOneRecord'; | import { useDestroyOneRecord } from '@/object-record/hooks/useDestroyOneRecord'; | ||||||
| import { useRestoreManyRecords } from '@/object-record/hooks/useRestoreManyRecords'; | import { useRestoreManyRecords } from '@/object-record/hooks/useRestoreManyRecords'; | ||||||
| import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; | import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; | ||||||
| @@ -28,9 +29,11 @@ const StyledContainer = styled.div` | |||||||
| export const ShowPageMoreButton = ({ | export const ShowPageMoreButton = ({ | ||||||
|   recordId, |   recordId, | ||||||
|   objectNameSingular, |   objectNameSingular, | ||||||
|  |   isRemote, | ||||||
| }: { | }: { | ||||||
|   recordId: string; |   recordId: string; | ||||||
|   objectNameSingular: string; |   objectNameSingular: string; | ||||||
|  |   isRemote: boolean; | ||||||
| }) => { | }) => { | ||||||
|   const { closeDropdown, toggleDropdown } = useDropdown('more-show-page'); |   const { closeDropdown, toggleDropdown } = useDropdown('more-show-page'); | ||||||
|   const navigationMemorizedUrl = useRecoilValue(navigationMemorizedUrlState); |   const navigationMemorizedUrl = useRecoilValue(navigationMemorizedUrlState); | ||||||
| @@ -66,6 +69,15 @@ export const ShowPageMoreButton = ({ | |||||||
|     recordStoreFamilyState(recordId), |     recordStoreFamilyState(recordId), | ||||||
|   ); |   ); | ||||||
|  |  | ||||||
|  |   if ( | ||||||
|  |     isObjectMetadataReadOnly({ | ||||||
|  |       isRemote, | ||||||
|  |       nameSingular: objectNameSingular, | ||||||
|  |     }) | ||||||
|  |   ) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|     <StyledContainer> |     <StyledContainer> | ||||||
|       <Dropdown |       <Dropdown | ||||||
|   | |||||||
| @@ -1,15 +1,21 @@ | |||||||
|  | import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar'; | ||||||
|  | import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; | ||||||
| import { useActivateWorkflowVersion } from '@/workflow/hooks/useActivateWorkflowVersion'; | import { useActivateWorkflowVersion } from '@/workflow/hooks/useActivateWorkflowVersion'; | ||||||
| import { useDeactivateWorkflowVersion } from '@/workflow/hooks/useDeactivateWorkflowVersion'; | import { useDeactivateWorkflowVersion } from '@/workflow/hooks/useDeactivateWorkflowVersion'; | ||||||
| import { useDeleteOneWorkflowVersion } from '@/workflow/hooks/useDeleteOneWorkflowVersion'; | import { useDeleteOneWorkflowVersion } from '@/workflow/hooks/useDeleteOneWorkflowVersion'; | ||||||
|  | import { useRunWorkflowVersion } from '@/workflow/hooks/useRunWorkflowVersion'; | ||||||
| import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion'; | import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion'; | ||||||
|  | import { useTheme } from '@emotion/react'; | ||||||
| import { | import { | ||||||
|   Button, |   Button, | ||||||
|   IconPlayerPlay, |   IconPlayerPlay, | ||||||
|   IconPlayerStop, |   IconPlayerStop, | ||||||
|   IconPower, |   IconPower, | ||||||
|  |   IconSettingsAutomation, | ||||||
|   IconTrash, |   IconTrash, | ||||||
|   isDefined, |   isDefined, | ||||||
| } from 'twenty-ui'; | } from 'twenty-ui'; | ||||||
|  | import { capitalize } from '~/utils/string/capitalize'; | ||||||
| import { assertWorkflowWithCurrentVersionIsDefined } from '../utils/assertWorkflowWithCurrentVersionIsDefined'; | import { assertWorkflowWithCurrentVersionIsDefined } from '../utils/assertWorkflowWithCurrentVersionIsDefined'; | ||||||
|  |  | ||||||
| export const RecordShowPageWorkflowHeader = ({ | export const RecordShowPageWorkflowHeader = ({ | ||||||
| @@ -26,6 +32,15 @@ export const RecordShowPageWorkflowHeader = ({ | |||||||
|   const { activateWorkflowVersion } = useActivateWorkflowVersion(); |   const { activateWorkflowVersion } = useActivateWorkflowVersion(); | ||||||
|   const { deactivateWorkflowVersion } = useDeactivateWorkflowVersion(); |   const { deactivateWorkflowVersion } = useDeactivateWorkflowVersion(); | ||||||
|   const { deleteOneWorkflowVersion } = useDeleteOneWorkflowVersion(); |   const { deleteOneWorkflowVersion } = useDeleteOneWorkflowVersion(); | ||||||
|  |   const { runWorkflowVersion } = useRunWorkflowVersion(); | ||||||
|  |  | ||||||
|  |   const { enqueueSnackBar } = useSnackBar(); | ||||||
|  |   const theme = useTheme(); | ||||||
|  |  | ||||||
|  |   const trigger = workflowWithCurrentVersion?.currentVersion.trigger; | ||||||
|  |  | ||||||
|  |   const canWorkflowBeTested = | ||||||
|  |     trigger?.type === 'MANUAL' && !trigger.settings.objectType; | ||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|     <> |     <> | ||||||
| @@ -34,7 +49,41 @@ export const RecordShowPageWorkflowHeader = ({ | |||||||
|         variant="secondary" |         variant="secondary" | ||||||
|         Icon={IconPlayerPlay} |         Icon={IconPlayerPlay} | ||||||
|         disabled={isWaitingForWorkflowWithCurrentVersion} |         disabled={isWaitingForWorkflowWithCurrentVersion} | ||||||
|         onClick={() => {}} |         onClick={async () => { | ||||||
|  |           assertWorkflowWithCurrentVersionIsDefined(workflowWithCurrentVersion); | ||||||
|  |  | ||||||
|  |           if (!canWorkflowBeTested) { | ||||||
|  |             enqueueSnackBar( | ||||||
|  |               'Trigger type should be Manual - when no record(s) are selected', | ||||||
|  |               { | ||||||
|  |                 variant: SnackBarVariant.Error, | ||||||
|  |                 title: 'Workflow cannot be tested', | ||||||
|  |                 icon: ( | ||||||
|  |                   <IconSettingsAutomation | ||||||
|  |                     size={16} | ||||||
|  |                     color={theme.snackBar.error.color} | ||||||
|  |                   /> | ||||||
|  |                 ), | ||||||
|  |               }, | ||||||
|  |             ); | ||||||
|  |             return; | ||||||
|  |           } | ||||||
|  |  | ||||||
|  |           await runWorkflowVersion({ | ||||||
|  |             workflowVersionId: workflowWithCurrentVersion.currentVersion.id, | ||||||
|  |           }); | ||||||
|  |  | ||||||
|  |           enqueueSnackBar('', { | ||||||
|  |             variant: SnackBarVariant.Success, | ||||||
|  |             title: `${capitalize(workflowWithCurrentVersion.name)} starting...`, | ||||||
|  |             icon: ( | ||||||
|  |               <IconSettingsAutomation | ||||||
|  |                 size={16} | ||||||
|  |                 color={theme.snackBar.success.color} | ||||||
|  |               /> | ||||||
|  |             ), | ||||||
|  |           }); | ||||||
|  |         }} | ||||||
|       /> |       /> | ||||||
|  |  | ||||||
|       {workflowWithCurrentVersion?.currentVersion?.status === 'DRAFT' && |       {workflowWithCurrentVersion?.currentVersion?.status === 'DRAFT' && | ||||||
|   | |||||||
| @@ -82,7 +82,7 @@ export const RecordShowPageWorkflowVersionHeader = ({ | |||||||
|     <> |     <> | ||||||
|       {showUseAsDraftButton ? ( |       {showUseAsDraftButton ? ( | ||||||
|         <Button |         <Button | ||||||
|           title={`Use as Draft${hasAlreadyDraftVersion ? ' (override)' : ''}`} |           title={'Use as Draft'} | ||||||
|           variant="secondary" |           variant="secondary" | ||||||
|           Icon={IconPencil} |           Icon={IconPencil} | ||||||
|           disabled={isWaitingForWorkflowVersion} |           disabled={isWaitingForWorkflowVersion} | ||||||
|   | |||||||
| @@ -15,10 +15,13 @@ export const useRunWorkflowVersion = () => { | |||||||
|     client: apolloMetadataClient, |     client: apolloMetadataClient, | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   const runWorkflowVersion = async ( |   const runWorkflowVersion = async ({ | ||||||
|     workflowVersionId: string, |     workflowVersionId, | ||||||
|     payload?: Record<string, any>, |     payload, | ||||||
|   ) => { |   }: { | ||||||
|  |     workflowVersionId: string; | ||||||
|  |     payload?: Record<string, any>; | ||||||
|  |   }) => { | ||||||
|     await mutate({ |     await mutate({ | ||||||
|       variables: { input: { workflowVersionId, payload } }, |       variables: { input: { workflowVersionId, payload } }, | ||||||
|     }); |     }); | ||||||
|   | |||||||
| @@ -34,6 +34,7 @@ export const RecordShowPageBaseHeader = ({ | |||||||
|         key="more" |         key="more" | ||||||
|         recordId={record?.id ?? '0'} |         recordId={record?.id ?? '0'} | ||||||
|         objectNameSingular={objectNameSingular} |         objectNameSingular={objectNameSingular} | ||||||
|  |         isRemote={objectMetadataItem.isRemote} | ||||||
|       /> |       /> | ||||||
|     </> |     </> | ||||||
|   ); |   ); | ||||||
|   | |||||||
| @@ -9,6 +9,10 @@ import { WorkflowCreateOnePostQueryHook } from 'src/modules/workflow/common/quer | |||||||
| import { WorkflowCreateOnePreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-create-one.pre-query.hook'; | import { WorkflowCreateOnePreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-create-one.pre-query.hook'; | ||||||
| import { WorkflowRunCreateManyPreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-run-create-many.pre-query.hook'; | import { WorkflowRunCreateManyPreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-run-create-many.pre-query.hook'; | ||||||
| import { WorkflowRunCreateOnePreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-run-create-one.pre-query.hook'; | import { WorkflowRunCreateOnePreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-run-create-one.pre-query.hook'; | ||||||
|  | import { WorkflowRunDeleteManyPreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-run-delete-many.pre-query.hook'; | ||||||
|  | import { WorkflowRunDeleteOnePreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-run-delete-one.pre-query.hook'; | ||||||
|  | import { WorkflowRunUpdateManyPreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-run-update-many.pre-query.hook'; | ||||||
|  | import { WorkflowRunUpdateOnePreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-run-update-one.pre-query.hook'; | ||||||
| import { WorkflowUpdateManyPreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-update-many.pre-query.hook'; | import { WorkflowUpdateManyPreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-update-many.pre-query.hook'; | ||||||
| import { WorkflowUpdateOnePreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-update-one.pre-query.hook'; | import { WorkflowUpdateOnePreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-update-one.pre-query.hook'; | ||||||
| import { WorkflowVersionCreateManyPreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-version-create-many.pre-query.hook'; | import { WorkflowVersionCreateManyPreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-version-create-many.pre-query.hook'; | ||||||
| @@ -31,6 +35,10 @@ import { WorkflowVersionValidationWorkspaceService } from 'src/modules/workflow/ | |||||||
|     WorkflowUpdateManyPreQueryHook, |     WorkflowUpdateManyPreQueryHook, | ||||||
|     WorkflowRunCreateOnePreQueryHook, |     WorkflowRunCreateOnePreQueryHook, | ||||||
|     WorkflowRunCreateManyPreQueryHook, |     WorkflowRunCreateManyPreQueryHook, | ||||||
|  |     WorkflowRunUpdateOnePreQueryHook, | ||||||
|  |     WorkflowRunUpdateManyPreQueryHook, | ||||||
|  |     WorkflowRunDeleteOnePreQueryHook, | ||||||
|  |     WorkflowRunDeleteManyPreQueryHook, | ||||||
|     WorkflowVersionCreateOnePreQueryHook, |     WorkflowVersionCreateOnePreQueryHook, | ||||||
|     WorkflowVersionCreateManyPreQueryHook, |     WorkflowVersionCreateManyPreQueryHook, | ||||||
|     WorkflowVersionUpdateOnePreQueryHook, |     WorkflowVersionUpdateOnePreQueryHook, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Thomas Trompette
					Thomas Trompette