diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/isRecordMatchingFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/isRecordMatchingFilter.ts index f6524d72dd..b96ba62c02 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/isRecordMatchingFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/isRecordMatchingFilter.ts @@ -285,12 +285,12 @@ export const isRecordMatchingFilter = ({ (fullNameFilter.firstName === undefined || isMatchingStringFilter({ stringFilter: fullNameFilter.firstName, - value: record[filterKey].firstName, + value: record[filterKey]?.firstName, })) && (fullNameFilter.lastName === undefined || isMatchingStringFilter({ stringFilter: fullNameFilter.lastName, - value: record[filterKey].lastName, + value: record[filterKey]?.lastName, })) ); } @@ -314,7 +314,7 @@ export const isRecordMatchingFilter = ({ return isMatchingStringFilter({ stringFilter: value, - value: record[filterKey][key], + value: record[filterKey]?.[key], }); }); } @@ -331,7 +331,7 @@ export const isRecordMatchingFilter = ({ return isMatchingStringFilter({ stringFilter: value, - value: record[filterKey][key], + value: record[filterKey]?.[key], }); }); } @@ -373,7 +373,7 @@ export const isRecordMatchingFilter = ({ if (isDefined(actorFilter.workspaceMemberId)) { return isMatchingUUIDFilter({ uuidFilter: actorFilter.workspaceMemberId, - value: record[filterKey].workspaceMemberId, + value: record[filterKey]?.workspaceMemberId, }); } @@ -381,7 +381,7 @@ export const isRecordMatchingFilter = ({ actorFilter.name === undefined || isMatchingStringFilter({ stringFilter: actorFilter.name, - value: record[filterKey].name, + value: record[filterKey]?.name, }) ); } @@ -394,7 +394,7 @@ export const isRecordMatchingFilter = ({ return isMatchingStringFilter({ stringFilter: emailsFilter.primaryEmail, - value: record[filterKey].primaryEmail, + value: record[filterKey]?.primaryEmail, }); } case FieldMetadataType.PHONES: { @@ -410,7 +410,7 @@ export const isRecordMatchingFilter = ({ return isMatchingStringFilter({ stringFilter: value, - value: record[filterKey][key], + value: record[filterKey]?.[key], }); }); } diff --git a/packages/twenty-server/src/modules/workflow/common/utils/set-all-iterators-step-infos-as-stopped.util.ts b/packages/twenty-server/src/modules/workflow/common/utils/set-all-iterators-step-infos-as-stopped.util.ts new file mode 100644 index 0000000000..ad61b1d874 --- /dev/null +++ b/packages/twenty-server/src/modules/workflow/common/utils/set-all-iterators-step-infos-as-stopped.util.ts @@ -0,0 +1,32 @@ +import { + StepStatus, + type WorkflowRunStepInfo, + type WorkflowRunStepInfos, +} from 'twenty-shared/workflow'; + +import { isWorkflowIteratorAction } from 'src/modules/workflow/workflow-executor/workflow-actions/iterator/guards/is-workflow-iterator-action.guard'; +import { type WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type'; + +export const setAllIteratorsStepInfosAsStopped = ({ + stepInfos, + steps, +}: { + stepInfos: WorkflowRunStepInfos; + steps: WorkflowAction[]; +}): Record => { + const stoppedStepInfos: Record = {}; + + for (const step of steps) { + if ( + stepInfos[step.id]?.status === StepStatus.RUNNING && + isWorkflowIteratorAction(step) + ) { + stoppedStepInfos[step.id] = { + ...stepInfos[step.id], + status: StepStatus.STOPPED, + }; + } + } + + return stoppedStepInfos; +}; diff --git a/packages/twenty-server/src/modules/workflow/workflow-runner/workspace-services/workflow-runner.workspace-service.ts b/packages/twenty-server/src/modules/workflow/workflow-runner/workspace-services/workflow-runner.workspace-service.ts index fdd5fd8507..a562bbd37e 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-runner/workspace-services/workflow-runner.workspace-service.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-runner/workspace-services/workflow-runner.workspace-service.ts @@ -16,6 +16,7 @@ import { WorkflowVersionStepExceptionCode, } from 'src/modules/workflow/common/exceptions/workflow-version-step.exception'; import { WorkflowRunStatus } from 'src/modules/workflow/common/standard-objects/workflow-run.workspace-entity'; +import { setAllIteratorsStepInfosAsStopped } from 'src/modules/workflow/common/utils/set-all-iterators-step-infos-as-stopped.util'; import { workflowHasRunningSteps } from 'src/modules/workflow/common/utils/workflow-has-running-steps.util'; import { WorkflowCommonWorkspaceService } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service'; import { WorkflowVersionStepOperationsWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step-operations.workspace-service'; @@ -218,17 +219,29 @@ export class WorkflowRunnerWorkspaceService { let newStatus: WorkflowRunStatus; - if ( - workflowHasRunningSteps({ - stepInfos: workflowRun.state.stepInfos, - steps: workflowRun.state.flow.steps, - }) - ) { + const stepInfos = workflowRun.state.stepInfos; + const steps = workflowRun.state.flow.steps; + + if (workflowHasRunningSteps({ stepInfos, steps })) { + const stoppedIteratorStepInfos = setAllIteratorsStepInfosAsStopped({ + stepInfos, + steps, + }); + + const mergedStepInfos = { + ...stepInfos, + ...stoppedIteratorStepInfos, + }; + await this.workflowRunWorkspaceService.updateWorkflowRun({ workflowRunId, workspaceId, partialUpdate: { status: WorkflowRunStatus.STOPPING, + state: { + ...workflowRun.state, + stepInfos: mergedStepInfos, + }, }, }); newStatus = WorkflowRunStatus.STOPPING; diff --git a/packages/twenty-ui/src/components/chip/Chip.tsx b/packages/twenty-ui/src/components/chip/Chip.tsx index cc53b8f5f1..3ef7f9883b 100644 --- a/packages/twenty-ui/src/components/chip/Chip.tsx +++ b/packages/twenty-ui/src/components/chip/Chip.tsx @@ -1,8 +1,10 @@ import { styled } from '@linaria/react'; import { type ReactNode } from 'react'; +import { isNonEmptyString } from '@sniptt/guards'; import { OverflowingTextWithTooltip } from '@ui/display/tooltip/OverflowingTextWithTooltip'; import { themeCssVariables } from '@ui/theme-constants'; +import { isDefined } from 'twenty-shared/utils'; export enum ChipSize { Large = 'large', @@ -197,7 +199,7 @@ export const Chip = ({ maxWidth={maxWidth} > {leftComponent} - {!isLabelHidden && label && label.trim() ? ( + {!isLabelHidden && isDefined(label) && isNonEmptyString(label) ? ( ) : !forceEmptyText && !isLabelHidden ? ( {emptyLabel}