Add UTC timezone label to CRON trigger form (#14674)

- Added 'Cron will be triggered at UTC time' notice below trigger
interval dropdown
- Positioned correctly between dropdown and expression field to match
design
- Only shows when Custom CRON option is selected

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
Omar Eltomy
2025-09-24 19:45:56 +02:00
committed by GitHub
co-authored by Félix Malfait Félix Malfait
parent 37ce5c48bb
commit 2af20a4cf0
36 changed files with 2093 additions and 121 deletions
@@ -1,8 +1,8 @@
import { WorkflowTriggerException } from 'src/modules/workflow/workflow-trigger/exceptions/workflow-trigger.exception';
import {
type WorkflowCronTrigger,
WorkflowTriggerType,
} from 'src/modules/workflow/workflow-trigger/types/workflow-trigger.type';
import { WorkflowTriggerException } from 'src/modules/workflow/workflow-trigger/exceptions/workflow-trigger.exception';
import { computeCronPatternFromSchedule } from 'src/modules/workflow/workflow-trigger/utils/compute-cron-pattern-from-schedule';
describe('computeCronPatternFromSchedule', () => {
@@ -20,7 +20,7 @@ describe('computeCronPatternFromSchedule', () => {
expect(computeCronPatternFromSchedule(trigger)).toBe('12 * * * *');
});
it('should throw an exception for unsupported pattern for CUSTOM type', () => {
it('should support 6-field cron patterns with seconds for CUSTOM type', () => {
const trigger: WorkflowCronTrigger = {
name: '',
type: WorkflowTriggerType.CRON,
@@ -31,11 +31,25 @@ describe('computeCronPatternFromSchedule', () => {
},
};
expect(computeCronPatternFromSchedule(trigger)).toBe('0 12 * * * *');
});
it('should throw an exception for invalid pattern for CUSTOM type', () => {
const trigger: WorkflowCronTrigger = {
name: '',
type: WorkflowTriggerType.CRON,
settings: {
type: 'CUSTOM',
pattern: '60 25 32 13 8',
outputSchema: {},
},
};
expect(() => computeCronPatternFromSchedule(trigger)).toThrow(
WorkflowTriggerException,
);
expect(() => computeCronPatternFromSchedule(trigger)).toThrow(
"Cron pattern '0 12 * * * *' is invalid",
"Cron pattern '60 25 32 13 8' is invalid",
);
});
@@ -1,5 +1,5 @@
import { t } from '@lingui/core/macro';
import cron from 'cron-validate';
import { CronExpressionParser } from 'cron-parser';
import {
WorkflowTriggerException,
@@ -8,11 +8,11 @@ import {
import { type WorkflowCronTrigger } from 'src/modules/workflow/workflow-trigger/types/workflow-trigger.type';
const validatePattern = (pattern: string) => {
const cronValidator = cron(pattern);
if (cronValidator.isError()) {
try {
CronExpressionParser.parse(pattern);
} catch (error) {
throw new WorkflowTriggerException(
`Cron pattern '${pattern}' is invalid`,
`Cron pattern '${pattern}' is invalid: ${error.message}`,
WorkflowTriggerExceptionCode.INVALID_WORKFLOW_TRIGGER,
{
userFriendlyMessage: t`Cron pattern '${pattern}' is invalid`,