Fix workflow dropdown hotkey scope (#11518)
The hokey scope was set on focus of the outermost container of the field inputs. When clicking on a dropdown inside this container, the hokey scope was set first by the dropdown and then by the focused container. This led to the previous hotkey scope being overwritten. The fix consists in moving the hokey scope setter on focus to the inner container. Before: https://github.com/user-attachments/assets/12538c5b-43ab-4b76-a867-7eda6992b1ea After: https://github.com/user-attachments/assets/002fedba-010c-41e9-bec6-d5d80cb2dcc5
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
||||||
import { FormFieldInputInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInputContainer';
|
import { FormFieldInputInnerContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInnerContainer';
|
||||||
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
||||||
import { VariableChipStandalone } from '@/object-record/record-field/form-types/components/VariableChipStandalone';
|
import { VariableChipStandalone } from '@/object-record/record-field/form-types/components/VariableChipStandalone';
|
||||||
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
||||||
@ -84,7 +84,7 @@ export const FormBooleanFieldInput = ({
|
|||||||
{label ? <InputLabel>{label}</InputLabel> : null}
|
{label ? <InputLabel>{label}</InputLabel> : null}
|
||||||
|
|
||||||
<FormFieldInputRowContainer>
|
<FormFieldInputRowContainer>
|
||||||
<FormFieldInputInputContainer
|
<FormFieldInputInnerContainer
|
||||||
hasRightElement={isDefined(VariablePicker) && !readonly}
|
hasRightElement={isDefined(VariablePicker) && !readonly}
|
||||||
>
|
>
|
||||||
{draftValue.type === 'static' ? (
|
{draftValue.type === 'static' ? (
|
||||||
@ -101,7 +101,7 @@ export const FormBooleanFieldInput = ({
|
|||||||
onRemove={readonly ? undefined : handleUnlinkVariable}
|
onRemove={readonly ? undefined : handleUnlinkVariable}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</FormFieldInputInputContainer>
|
</FormFieldInputInnerContainer>
|
||||||
|
|
||||||
{VariablePicker && !readonly ? (
|
{VariablePicker && !readonly ? (
|
||||||
<VariablePicker
|
<VariablePicker
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
||||||
import { FormFieldInputInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInputContainer';
|
import { FormFieldInputInnerContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInnerContainer';
|
||||||
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
||||||
import { VariableChipStandalone } from '@/object-record/record-field/form-types/components/VariableChipStandalone';
|
import { VariableChipStandalone } from '@/object-record/record-field/form-types/components/VariableChipStandalone';
|
||||||
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
||||||
@ -32,7 +32,7 @@ import { isDefined } from 'twenty-shared/utils';
|
|||||||
import { TEXT_INPUT_STYLE } from 'twenty-ui/theme';
|
import { TEXT_INPUT_STYLE } from 'twenty-ui/theme';
|
||||||
import { Nullable } from 'twenty-ui/utilities';
|
import { Nullable } from 'twenty-ui/utilities';
|
||||||
|
|
||||||
const StyledInputContainer = styled(FormFieldInputInputContainer)`
|
const StyledInputContainer = styled(FormFieldInputInnerContainer)`
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
grid-template-rows: 1fr 0px;
|
grid-template-rows: 1fr 0px;
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { ReactNode } from 'react';
|
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`
|
const StyledFormFieldInputContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -16,27 +14,8 @@ export const FormFieldInputContainer = ({
|
|||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
testId?: string;
|
testId?: string;
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
|
||||||
goBackToPreviousHotkeyScope,
|
|
||||||
setHotkeyScopeAndMemorizePreviousScope,
|
|
||||||
} = usePreviousHotkeyScope();
|
|
||||||
|
|
||||||
const onFocus = () => {
|
|
||||||
setHotkeyScopeAndMemorizePreviousScope(
|
|
||||||
FormFieldInputHotKeyScope.FormFieldInput,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onBlur = () => {
|
|
||||||
goBackToPreviousHotkeyScope();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledFormFieldInputContainer
|
<StyledFormFieldInputContainer data-testid={testId}>
|
||||||
data-testid={testId}
|
|
||||||
onFocus={onFocus}
|
|
||||||
onBlur={onBlur}
|
|
||||||
>
|
|
||||||
{children}
|
{children}
|
||||||
</StyledFormFieldInputContainer>
|
</StyledFormFieldInputContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -0,0 +1,90 @@
|
|||||||
|
import { FormFieldInputHotKeyScope } from '@/object-record/record-field/form-types/constants/FormFieldInputHotKeyScope';
|
||||||
|
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||||
|
import { css } from '@emotion/react';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
import { forwardRef, HTMLAttributes, Ref } from 'react';
|
||||||
|
|
||||||
|
type FormFieldInputInnerContainerProps = {
|
||||||
|
hasRightElement: boolean;
|
||||||
|
multiline?: boolean;
|
||||||
|
readonly?: boolean;
|
||||||
|
preventSetHotkeyScope?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const StyledFormFieldInputInnerContainer = styled.div<FormFieldInputInnerContainerProps>`
|
||||||
|
background-color: ${({ theme }) => theme.background.transparent.lighter};
|
||||||
|
border: 1px solid ${({ theme }) => theme.border.color.medium};
|
||||||
|
border-top-left-radius: ${({ theme }) => theme.border.radius.sm};
|
||||||
|
border-bottom-left-radius: ${({ theme }) => theme.border.radius.sm};
|
||||||
|
|
||||||
|
${({ multiline, hasRightElement, theme }) =>
|
||||||
|
multiline || !hasRightElement
|
||||||
|
? css`
|
||||||
|
border-right: auto;
|
||||||
|
border-bottom-right-radius: ${theme.border.radius.sm};
|
||||||
|
border-top-right-radius: ${theme.border.radius.sm};
|
||||||
|
`
|
||||||
|
: css`
|
||||||
|
border-right: none;
|
||||||
|
border-bottom-right-radius: none;
|
||||||
|
border-top-right-radius: none;
|
||||||
|
`}
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
overflow: ${({ multiline }) => (multiline ? 'auto' : 'hidden')};
|
||||||
|
width: 100%;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const FormFieldInputInnerContainer = forwardRef(
|
||||||
|
(
|
||||||
|
{
|
||||||
|
className,
|
||||||
|
children,
|
||||||
|
onFocus,
|
||||||
|
onBlur,
|
||||||
|
hasRightElement,
|
||||||
|
multiline,
|
||||||
|
readonly,
|
||||||
|
preventSetHotkeyScope = false,
|
||||||
|
}: HTMLAttributes<HTMLDivElement> & FormFieldInputInnerContainerProps,
|
||||||
|
ref: Ref<HTMLDivElement>,
|
||||||
|
) => {
|
||||||
|
const {
|
||||||
|
goBackToPreviousHotkeyScope,
|
||||||
|
setHotkeyScopeAndMemorizePreviousScope,
|
||||||
|
} = usePreviousHotkeyScope();
|
||||||
|
|
||||||
|
const handleFocus = (e: React.FocusEvent<HTMLDivElement>) => {
|
||||||
|
onFocus?.(e);
|
||||||
|
|
||||||
|
if (!preventSetHotkeyScope) {
|
||||||
|
setHotkeyScopeAndMemorizePreviousScope(
|
||||||
|
FormFieldInputHotKeyScope.FormFieldInput,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleBlur = (e: React.FocusEvent<HTMLDivElement>) => {
|
||||||
|
onBlur?.(e);
|
||||||
|
|
||||||
|
if (!preventSetHotkeyScope) {
|
||||||
|
goBackToPreviousHotkeyScope();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledFormFieldInputInnerContainer
|
||||||
|
ref={ref}
|
||||||
|
className={className}
|
||||||
|
hasRightElement={hasRightElement}
|
||||||
|
multiline={multiline}
|
||||||
|
readonly={readonly}
|
||||||
|
onFocus={handleFocus}
|
||||||
|
onBlur={handleBlur}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</StyledFormFieldInputInnerContainer>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
@ -1,33 +0,0 @@
|
|||||||
import { css } from '@emotion/react';
|
|
||||||
import styled from '@emotion/styled';
|
|
||||||
|
|
||||||
const StyledFormFieldInputInputContainer = styled.div<{
|
|
||||||
hasRightElement: boolean;
|
|
||||||
multiline?: boolean;
|
|
||||||
readonly?: boolean;
|
|
||||||
}>`
|
|
||||||
background-color: ${({ theme }) => theme.background.transparent.lighter};
|
|
||||||
border: 1px solid ${({ theme }) => theme.border.color.medium};
|
|
||||||
border-top-left-radius: ${({ theme }) => theme.border.radius.sm};
|
|
||||||
border-bottom-left-radius: ${({ theme }) => theme.border.radius.sm};
|
|
||||||
|
|
||||||
${({ multiline, hasRightElement, theme }) =>
|
|
||||||
multiline || !hasRightElement
|
|
||||||
? css`
|
|
||||||
border-right: auto;
|
|
||||||
border-bottom-right-radius: ${theme.border.radius.sm};
|
|
||||||
border-top-right-radius: ${theme.border.radius.sm};
|
|
||||||
`
|
|
||||||
: css`
|
|
||||||
border-right: none;
|
|
||||||
border-bottom-right-radius: none;
|
|
||||||
border-top-right-radius: none;
|
|
||||||
`}
|
|
||||||
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: flex;
|
|
||||||
overflow: ${({ multiline }) => (multiline ? 'auto' : 'hidden')};
|
|
||||||
width: 100%;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const FormFieldInputInputContainer = StyledFormFieldInputInputContainer;
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
||||||
import { FormFieldInputInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInputContainer';
|
import { FormFieldInputInnerContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInnerContainer';
|
||||||
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
||||||
import { VariableChipStandalone } from '@/object-record/record-field/form-types/components/VariableChipStandalone';
|
import { VariableChipStandalone } from '@/object-record/record-field/form-types/components/VariableChipStandalone';
|
||||||
import { FormMultiSelectFieldInputHotKeyScope } from '@/object-record/record-field/form-types/constants/FormMultiSelectFieldInputHotKeyScope';
|
import { FormMultiSelectFieldInputHotKeyScope } from '@/object-record/record-field/form-types/constants/FormMultiSelectFieldInputHotKeyScope';
|
||||||
@ -17,9 +17,9 @@ import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariabl
|
|||||||
import { useTheme } from '@emotion/react';
|
import { useTheme } from '@emotion/react';
|
||||||
import { useId, useState } from 'react';
|
import { useId, useState } from 'react';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
import { VisibilityHidden } from 'twenty-ui/accessibility';
|
||||||
import { IconChevronDown } from 'twenty-ui/display';
|
import { IconChevronDown } from 'twenty-ui/display';
|
||||||
import { SelectOption } from 'twenty-ui/input';
|
import { SelectOption } from 'twenty-ui/input';
|
||||||
import { VisibilityHidden } from 'twenty-ui/accessibility';
|
|
||||||
|
|
||||||
type FormMultiSelectFieldInputProps = {
|
type FormMultiSelectFieldInputProps = {
|
||||||
label?: string;
|
label?: string;
|
||||||
@ -185,7 +185,7 @@ export const FormMultiSelectFieldInput = ({
|
|||||||
{label ? <InputLabel>{label}</InputLabel> : null}
|
{label ? <InputLabel>{label}</InputLabel> : null}
|
||||||
|
|
||||||
<FormFieldInputRowContainer>
|
<FormFieldInputRowContainer>
|
||||||
<FormFieldInputInputContainer
|
<FormFieldInputInnerContainer
|
||||||
hasRightElement={isDefined(VariablePicker) && !readonly}
|
hasRightElement={isDefined(VariablePicker) && !readonly}
|
||||||
>
|
>
|
||||||
{draftValue.type === 'static' ? (
|
{draftValue.type === 'static' ? (
|
||||||
@ -231,7 +231,7 @@ export const FormMultiSelectFieldInput = ({
|
|||||||
onRemove={readonly ? undefined : handleUnlinkVariable}
|
onRemove={readonly ? undefined : handleUnlinkVariable}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</FormFieldInputInputContainer>
|
</FormFieldInputInnerContainer>
|
||||||
<StyledSelectInputContainer>
|
<StyledSelectInputContainer>
|
||||||
{draftValue.type === 'static' &&
|
{draftValue.type === 'static' &&
|
||||||
draftValue.editingMode === 'edit' && (
|
draftValue.editingMode === 'edit' && (
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
||||||
import { FormFieldInputInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInputContainer';
|
import { FormFieldInputInnerContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInnerContainer';
|
||||||
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
||||||
import { VariableChipStandalone } from '@/object-record/record-field/form-types/components/VariableChipStandalone';
|
import { VariableChipStandalone } from '@/object-record/record-field/form-types/components/VariableChipStandalone';
|
||||||
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
||||||
@ -108,7 +108,7 @@ export const FormNumberFieldInput = ({
|
|||||||
{label ? <InputLabel htmlFor={inputId}>{label}</InputLabel> : null}
|
{label ? <InputLabel htmlFor={inputId}>{label}</InputLabel> : null}
|
||||||
|
|
||||||
<FormFieldInputRowContainer>
|
<FormFieldInputRowContainer>
|
||||||
<FormFieldInputInputContainer
|
<FormFieldInputInnerContainer
|
||||||
hasRightElement={isDefined(VariablePicker) && !readonly}
|
hasRightElement={isDefined(VariablePicker) && !readonly}
|
||||||
onBlur={onBlur}
|
onBlur={onBlur}
|
||||||
>
|
>
|
||||||
@ -128,7 +128,7 @@ export const FormNumberFieldInput = ({
|
|||||||
onRemove={readonly ? undefined : handleUnlinkVariable}
|
onRemove={readonly ? undefined : handleUnlinkVariable}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</FormFieldInputInputContainer>
|
</FormFieldInputInnerContainer>
|
||||||
|
|
||||||
{VariablePicker && !readonly ? (
|
{VariablePicker && !readonly ? (
|
||||||
<VariablePicker
|
<VariablePicker
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
||||||
import { FormFieldInputInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInputContainer';
|
import { FormFieldInputInnerContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInnerContainer';
|
||||||
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
||||||
import { TextVariableEditor } from '@/object-record/record-field/form-types/components/TextVariableEditor';
|
import { TextVariableEditor } from '@/object-record/record-field/form-types/components/TextVariableEditor';
|
||||||
import { useTextVariableEditor } from '@/object-record/record-field/form-types/hooks/useTextVariableEditor';
|
import { useTextVariableEditor } from '@/object-record/record-field/form-types/hooks/useTextVariableEditor';
|
||||||
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
||||||
|
import { InputErrorHelper } from '@/ui/input/components/InputErrorHelper';
|
||||||
import { InputLabel } from '@/ui/input/components/InputLabel';
|
import { InputLabel } from '@/ui/input/components/InputLabel';
|
||||||
import { useId } from 'react';
|
import { useId } from 'react';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { turnIntoEmptyStringIfWhitespacesOnly } from '~/utils/string/turnIntoEmptyStringIfWhitespacesOnly';
|
import { turnIntoEmptyStringIfWhitespacesOnly } from '~/utils/string/turnIntoEmptyStringIfWhitespacesOnly';
|
||||||
import { InputErrorHelper } from '@/ui/input/components/InputErrorHelper';
|
|
||||||
|
|
||||||
type FormRawJsonFieldInputProps = {
|
type FormRawJsonFieldInputProps = {
|
||||||
label?: string;
|
label?: string;
|
||||||
@ -70,13 +70,13 @@ export const FormRawJsonFieldInput = ({
|
|||||||
{label ? <InputLabel>{label}</InputLabel> : null}
|
{label ? <InputLabel>{label}</InputLabel> : null}
|
||||||
|
|
||||||
<FormFieldInputRowContainer multiline>
|
<FormFieldInputRowContainer multiline>
|
||||||
<FormFieldInputInputContainer
|
<FormFieldInputInnerContainer
|
||||||
hasRightElement={isDefined(VariablePicker) && !readonly}
|
hasRightElement={isDefined(VariablePicker) && !readonly}
|
||||||
multiline
|
multiline
|
||||||
onBlur={onBlur}
|
onBlur={onBlur}
|
||||||
>
|
>
|
||||||
<TextVariableEditor editor={editor} multiline readonly={readonly} />
|
<TextVariableEditor editor={editor} multiline readonly={readonly} />
|
||||||
</FormFieldInputInputContainer>
|
</FormFieldInputInnerContainer>
|
||||||
|
|
||||||
{VariablePicker && !readonly && (
|
{VariablePicker && !readonly && (
|
||||||
<VariablePicker
|
<VariablePicker
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
||||||
import { FormFieldInputInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInputContainer';
|
import { FormFieldInputInnerContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInnerContainer';
|
||||||
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
||||||
import { VariableChipStandalone } from '@/object-record/record-field/form-types/components/VariableChipStandalone';
|
import { VariableChipStandalone } from '@/object-record/record-field/form-types/components/VariableChipStandalone';
|
||||||
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
||||||
@ -134,14 +134,14 @@ export const FormSelectFieldInput = ({
|
|||||||
disabled={readonly}
|
disabled={readonly}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<FormFieldInputInputContainer
|
<FormFieldInputInnerContainer
|
||||||
hasRightElement={isDefined(VariablePicker) && !readonly}
|
hasRightElement={isDefined(VariablePicker) && !readonly}
|
||||||
>
|
>
|
||||||
<VariableChipStandalone
|
<VariableChipStandalone
|
||||||
rawVariableName={draftValue.value}
|
rawVariableName={draftValue.value}
|
||||||
onRemove={readonly ? undefined : handleUnlinkVariable}
|
onRemove={readonly ? undefined : handleUnlinkVariable}
|
||||||
/>
|
/>
|
||||||
</FormFieldInputInputContainer>
|
</FormFieldInputInnerContainer>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{isDefined(VariablePicker) && !readonly && (
|
{isDefined(VariablePicker) && !readonly && (
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
||||||
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
||||||
import { FormFieldInputInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInputContainer';
|
import { FormFieldInputInnerContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInnerContainer';
|
||||||
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
||||||
import { FormSingleRecordFieldChip } from '@/object-record/record-field/form-types/components/FormSingleRecordFieldChip';
|
import { FormSingleRecordFieldChip } from '@/object-record/record-field/form-types/components/FormSingleRecordFieldChip';
|
||||||
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
||||||
@ -20,7 +20,7 @@ import { isDefined, isValidUuid } from 'twenty-shared/utils';
|
|||||||
import { IconChevronDown, IconForbid } from 'twenty-ui/display';
|
import { IconChevronDown, IconForbid } from 'twenty-ui/display';
|
||||||
import { LightIconButton } from 'twenty-ui/input';
|
import { LightIconButton } from 'twenty-ui/input';
|
||||||
|
|
||||||
const StyledFormSelectContainer = styled(FormFieldInputInputContainer)`
|
const StyledFormSelectContainer = styled(FormFieldInputInnerContainer)`
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding-right: ${({ theme }) => theme.spacing(1)};
|
padding-right: ${({ theme }) => theme.spacing(1)};
|
||||||
@ -132,6 +132,7 @@ export const FormSingleRecordPicker = ({
|
|||||||
<FormFieldInputRowContainer>
|
<FormFieldInputRowContainer>
|
||||||
<StyledFormSelectContainer
|
<StyledFormSelectContainer
|
||||||
hasRightElement={isDefined(VariablePicker) && !disabled}
|
hasRightElement={isDefined(VariablePicker) && !disabled}
|
||||||
|
preventSetHotkeyScope={true}
|
||||||
>
|
>
|
||||||
<FormSingleRecordFieldChip
|
<FormSingleRecordFieldChip
|
||||||
draftValue={draftValue}
|
draftValue={draftValue}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
||||||
import { FormFieldInputInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInputContainer';
|
import { FormFieldInputInnerContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInnerContainer';
|
||||||
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
||||||
import { TextVariableEditor } from '@/object-record/record-field/form-types/components/TextVariableEditor';
|
import { TextVariableEditor } from '@/object-record/record-field/form-types/components/TextVariableEditor';
|
||||||
import { useTextVariableEditor } from '@/object-record/record-field/form-types/hooks/useTextVariableEditor';
|
import { useTextVariableEditor } from '@/object-record/record-field/form-types/hooks/useTextVariableEditor';
|
||||||
@ -70,7 +70,7 @@ export const FormTextFieldInput = ({
|
|||||||
{label ? <InputLabel>{label}</InputLabel> : null}
|
{label ? <InputLabel>{label}</InputLabel> : null}
|
||||||
|
|
||||||
<FormFieldInputRowContainer multiline={multiline}>
|
<FormFieldInputRowContainer multiline={multiline}>
|
||||||
<FormFieldInputInputContainer
|
<FormFieldInputInnerContainer
|
||||||
hasRightElement={isDefined(VariablePicker) && !readonly}
|
hasRightElement={isDefined(VariablePicker) && !readonly}
|
||||||
multiline={multiline}
|
multiline={multiline}
|
||||||
onBlur={onBlur}
|
onBlur={onBlur}
|
||||||
@ -80,7 +80,7 @@ export const FormTextFieldInput = ({
|
|||||||
multiline={multiline}
|
multiline={multiline}
|
||||||
readonly={readonly}
|
readonly={readonly}
|
||||||
/>
|
/>
|
||||||
</FormFieldInputInputContainer>
|
</FormFieldInputInnerContainer>
|
||||||
|
|
||||||
{VariablePicker && !readonly ? (
|
{VariablePicker && !readonly ? (
|
||||||
<VariablePicker
|
<VariablePicker
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
||||||
import { FormFieldInputInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInputContainer';
|
import { FormFieldInputInnerContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInnerContainer';
|
||||||
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
||||||
import { VariableChipStandalone } from '@/object-record/record-field/form-types/components/VariableChipStandalone';
|
import { VariableChipStandalone } from '@/object-record/record-field/form-types/components/VariableChipStandalone';
|
||||||
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
||||||
@ -94,7 +94,7 @@ export const FormUuidFieldInput = ({
|
|||||||
{label ? <InputLabel htmlFor={inputId}>{label}</InputLabel> : null}
|
{label ? <InputLabel htmlFor={inputId}>{label}</InputLabel> : null}
|
||||||
|
|
||||||
<FormFieldInputRowContainer>
|
<FormFieldInputRowContainer>
|
||||||
<FormFieldInputInputContainer
|
<FormFieldInputInnerContainer
|
||||||
hasRightElement={isDefined(VariablePicker) && !readonly}
|
hasRightElement={isDefined(VariablePicker) && !readonly}
|
||||||
>
|
>
|
||||||
{draftValue.type === 'static' ? (
|
{draftValue.type === 'static' ? (
|
||||||
@ -113,7 +113,7 @@ export const FormUuidFieldInput = ({
|
|||||||
onRemove={readonly ? undefined : handleUnlinkVariable}
|
onRemove={readonly ? undefined : handleUnlinkVariable}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</FormFieldInputInputContainer>
|
</FormFieldInputInnerContainer>
|
||||||
|
|
||||||
{VariablePicker && !readonly ? (
|
{VariablePicker && !readonly ? (
|
||||||
<VariablePicker
|
<VariablePicker
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
|
||||||
import { FormFieldInputInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInputContainer';
|
import { FormFieldInputInnerContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInnerContainer';
|
||||||
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
|
||||||
import { InputLabel } from '@/ui/input/components/InputLabel';
|
import { InputLabel } from '@/ui/input/components/InputLabel';
|
||||||
import { WorkflowFormAction } from '@/workflow/types/Workflow';
|
import { WorkflowFormAction } from '@/workflow/types/Workflow';
|
||||||
@ -200,7 +200,7 @@ export const WorkflowEditActionFormBuilder = ({
|
|||||||
onMouseLeave={() => setHoveredField(null)}
|
onMouseLeave={() => setHoveredField(null)}
|
||||||
>
|
>
|
||||||
<FormFieldInputRowContainer>
|
<FormFieldInputRowContainer>
|
||||||
<FormFieldInputInputContainer
|
<FormFieldInputInnerContainer
|
||||||
hasRightElement={false}
|
hasRightElement={false}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
handleFieldClick(field.id);
|
handleFieldClick(field.id);
|
||||||
@ -220,7 +220,7 @@ export const WorkflowEditActionFormBuilder = ({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</StyledFieldContainer>
|
</StyledFieldContainer>
|
||||||
</FormFieldInputInputContainer>
|
</FormFieldInputInnerContainer>
|
||||||
</FormFieldInputRowContainer>
|
</FormFieldInputRowContainer>
|
||||||
{!actionOptions.readonly &&
|
{!actionOptions.readonly &&
|
||||||
(isFieldSelected(field.id) || isFieldHovered(field.id)) && (
|
(isFieldSelected(field.id) || isFieldHovered(field.id)) && (
|
||||||
@ -263,7 +263,7 @@ export const WorkflowEditActionFormBuilder = ({
|
|||||||
<StyledRowContainer>
|
<StyledRowContainer>
|
||||||
<FormFieldInputContainer>
|
<FormFieldInputContainer>
|
||||||
<FormFieldInputRowContainer>
|
<FormFieldInputRowContainer>
|
||||||
<FormFieldInputInputContainer
|
<FormFieldInputInnerContainer
|
||||||
hasRightElement={false}
|
hasRightElement={false}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const { label, name } = getDefaultFormFieldSettings(
|
const { label, name } = getDefaultFormFieldSettings(
|
||||||
@ -296,7 +296,7 @@ export const WorkflowEditActionFormBuilder = ({
|
|||||||
{t`Add Field`}
|
{t`Add Field`}
|
||||||
</StyledAddFieldButtonContentContainer>
|
</StyledAddFieldButtonContentContainer>
|
||||||
</StyledFieldContainer>
|
</StyledFieldContainer>
|
||||||
</FormFieldInputInputContainer>
|
</FormFieldInputInnerContainer>
|
||||||
</FormFieldInputRowContainer>
|
</FormFieldInputRowContainer>
|
||||||
</FormFieldInputContainer>
|
</FormFieldInputContainer>
|
||||||
</StyledRowContainer>
|
</StyledRowContainer>
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/StyledDropdownButtonContainer';
|
import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/StyledDropdownButtonContainer';
|
||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdownV2 } from '@/ui/layout/dropdown/hooks/useDropdownV2';
|
||||||
|
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||||
|
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
||||||
import { WorkflowVariablesDropdownFieldItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownFieldItems';
|
import { WorkflowVariablesDropdownFieldItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownFieldItems';
|
||||||
import { WorkflowVariablesDropdownObjectItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownObjectItems';
|
import { WorkflowVariablesDropdownObjectItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownObjectItems';
|
||||||
import { WorkflowVariablesDropdownWorkflowStepItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownWorkflowStepItems';
|
import { WorkflowVariablesDropdownWorkflowStepItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownWorkflowStepItems';
|
||||||
@ -11,6 +13,7 @@ import { StepOutputSchema } from '@/workflow/workflow-variables/types/StepOutput
|
|||||||
import { useTheme } from '@emotion/react';
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { IconVariablePlus } from 'twenty-ui/display';
|
import { IconVariablePlus } from 'twenty-ui/display';
|
||||||
|
|
||||||
@ -43,7 +46,10 @@ export const WorkflowVariablesDropdown = ({
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const dropdownId = `${SEARCH_VARIABLES_DROPDOWN_ID}-${inputId}`;
|
const dropdownId = `${SEARCH_VARIABLES_DROPDOWN_ID}-${inputId}`;
|
||||||
const { isDropdownOpen, closeDropdown } = useDropdown(dropdownId);
|
const isDropdownOpen = useRecoilValue(
|
||||||
|
extractComponentState(isDropdownOpenComponentState, dropdownId),
|
||||||
|
);
|
||||||
|
const { closeDropdown } = useDropdownV2();
|
||||||
const availableVariablesInWorkflowStep = useAvailableVariablesInWorkflowStep({
|
const availableVariablesInWorkflowStep = useAvailableVariablesInWorkflowStep({
|
||||||
objectNameSingularToSelect,
|
objectNameSingularToSelect,
|
||||||
});
|
});
|
||||||
@ -68,7 +74,7 @@ export const WorkflowVariablesDropdown = ({
|
|||||||
const handleSubItemSelect = (subItem: string) => {
|
const handleSubItemSelect = (subItem: string) => {
|
||||||
onVariableSelect(subItem);
|
onVariableSelect(subItem);
|
||||||
setSelectedStep(initialStep);
|
setSelectedStep(initialStep);
|
||||||
closeDropdown();
|
closeDropdown(dropdownId);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBack = () => {
|
const handleBack = () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user