360 workflow implement workflow cron triggers frontend 2 (#10051)

as title, closes https://github.com/twentyhq/core-team-issues/issues/360

## Cron Setting behavior

https://github.com/user-attachments/assets/0de3a8b9-d899-4455-a945-20c7541c3053

## Cron running behavior


https://github.com/user-attachments/assets/4c33f167-857c-4fcb-9dbe-0f9b661c9e61
This commit is contained in:
martmull
2025-02-07 17:15:03 +01:00
committed by GitHub
parent 988ab9697c
commit ead626c2ec
36 changed files with 826 additions and 19 deletions

View File

@ -1,10 +0,0 @@
import styled from '@emotion/styled';
const StyledFormFieldHint = styled.div`
color: ${({ theme }) => theme.font.color.light};
font-size: ${({ theme }) => theme.font.size.xs};
font-weight: ${({ theme }) => theme.font.weight.regular};
margin-top: ${({ theme }) => theme.spacing(1)};
`;
export const FormFieldHint = StyledFormFieldHint;

View File

@ -1,4 +1,7 @@
import styled from '@emotion/styled';
import { ReactNode } from 'react';
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
import { FormFieldInputHotKeyScope } from '@/object-record/record-field/form-types/constants/FormFieldInputHotKeyScope';
const StyledFormFieldInputContainer = styled.div`
display: flex;
@ -6,4 +9,35 @@ const StyledFormFieldInputContainer = styled.div`
width: 100%;
`;
export const FormFieldInputContainer = StyledFormFieldInputContainer;
export const FormFieldInputContainer = ({
children,
testId,
}: {
children: ReactNode;
testId?: string;
}) => {
const {
goBackToPreviousHotkeyScope,
setHotkeyScopeAndMemorizePreviousScope,
} = usePreviousHotkeyScope();
const onFocus = () => {
setHotkeyScopeAndMemorizePreviousScope(
FormFieldInputHotKeyScope.FormFieldInput,
);
};
const onBlur = () => {
goBackToPreviousHotkeyScope();
};
return (
<StyledFormFieldInputContainer
data-testid={testId}
onFocus={onFocus}
onBlur={onBlur}
>
{children}
</StyledFormFieldInputContainer>
);
};

View File

@ -178,7 +178,7 @@ export const FormMultiSelectFieldInput = ({
const placeholderText = placeholder ?? label;
return (
<FormFieldInputContainer data-testid={testId}>
<FormFieldInputContainer testId={testId}>
{label ? <InputLabel>{label}</InputLabel> : null}
<FormFieldInputRowContainer>

View File

@ -1,4 +1,3 @@
import { FormFieldHint } from '@/object-record/record-field/form-types/components/FormFieldHint';
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
import { FormFieldInputInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInputContainer';
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
@ -14,6 +13,8 @@ import {
canBeCastAsNumberOrNull,
castAsNumberOrNull,
} from '~/utils/cast-as-number-or-null';
import { InputErrorHelper } from '@/ui/input/components/InputErrorHelper';
import { InputHint } from '@/ui/input/components/InputHint';
const StyledInput = styled(TextInput)`
padding: ${({ theme }) => `${theme.spacing(1)} ${theme.spacing(2)}`};
@ -21,9 +22,11 @@ const StyledInput = styled(TextInput)`
type FormNumberFieldInputProps = {
label?: string;
error?: string;
placeholder: string;
defaultValue: number | string | undefined;
onPersist: (value: number | null | string) => void;
onBlur?: () => void;
VariablePicker?: VariablePickerComponent;
hint?: string;
readonly?: boolean;
@ -31,9 +34,11 @@ type FormNumberFieldInputProps = {
export const FormNumberFieldInput = ({
label,
error,
placeholder,
defaultValue,
onPersist,
onBlur,
VariablePicker,
hint,
readonly,
@ -105,6 +110,7 @@ export const FormNumberFieldInput = ({
<FormFieldInputRowContainer>
<FormFieldInputInputContainer
hasRightElement={isDefined(VariablePicker) && !readonly}
onBlur={onBlur}
>
{draftValue.type === 'static' ? (
<StyledInput
@ -132,7 +138,8 @@ export const FormNumberFieldInput = ({
) : null}
</FormFieldInputRowContainer>
{hint ? <FormFieldHint>{hint}</FormFieldHint> : null}
{hint ? <InputHint>{hint}</InputHint> : null}
{error && <InputErrorHelper>{error}</InputErrorHelper>}
</FormFieldInputContainer>
);
};

View File

@ -8,12 +8,17 @@ import { InputLabel } from '@/ui/input/components/InputLabel';
import { parseEditorContent } from '@/workflow/workflow-variables/utils/parseEditorContent';
import { useId } from 'react';
import { isDefined } from 'twenty-shared';
import { InputErrorHelper } from '@/ui/input/components/InputErrorHelper';
import { InputHint } from '@/ui/input/components/InputHint';
type FormTextFieldInputProps = {
label?: string;
error?: string;
hint?: string;
defaultValue: string | undefined;
placeholder: string;
onPersist: (value: string) => void;
onBlur?: () => void;
multiline?: boolean;
readonly?: boolean;
VariablePicker?: VariablePickerComponent;
@ -21,9 +26,12 @@ type FormTextFieldInputProps = {
export const FormTextFieldInput = ({
label,
error,
hint,
defaultValue,
placeholder,
onPersist,
onBlur,
multiline,
readonly,
VariablePicker,
@ -65,6 +73,7 @@ export const FormTextFieldInput = ({
<FormFieldInputInputContainer
hasRightElement={isDefined(VariablePicker) && !readonly}
multiline={multiline}
onBlur={onBlur}
>
<TextVariableEditor
editor={editor}
@ -81,6 +90,8 @@ export const FormTextFieldInput = ({
/>
) : null}
</FormFieldInputRowContainer>
{hint && <InputHint>{hint}</InputHint>}
{error && <InputErrorHelper>{error}</InputErrorHelper>}
</FormFieldInputContainer>
);
};

View File

@ -0,0 +1,3 @@
export enum FormFieldInputHotKeyScope {
FormFieldInput = 'form-field-input',
}