Bug fixes batch (#18457)

Fixes https://github.com/twentyhq/twenty/issues/18181

Fixes https://github.com/twentyhq/twenty/issues/16842
Iterators remain running, which prevent the stopping state to eventually
become stopped

Fixes https://github.com/twentyhq/twenty/issues/18186
This commit is contained in:
Thomas Trompette
2026-03-06 14:20:54 +01:00
committed by GitHub
parent f65aafe96b
commit 1f1da901ea
4 changed files with 62 additions and 15 deletions
@@ -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],
});
});
}
@@ -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<string, WorkflowRunStepInfo> => {
const stoppedStepInfos: Record<string, WorkflowRunStepInfo> = {};
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;
};
@@ -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;
@@ -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) ? (
<OverflowingTextWithTooltip size={size} text={label} />
) : !forceEmptyText && !isLabelHidden ? (
<StyledDiv>{emptyLabel}</StyledDiv>