Files
twenty/packages/twenty-front/src/modules/workflow/search-variables/components/SearchVariablesDropdown.tsx
2024-11-20 17:38:35 +00:00

127 lines
4.0 KiB
TypeScript

import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/StyledDropdownButtonContainer';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { SearchVariablesDropdownStepItem } from '@/workflow/search-variables/components/SearchVariablesDropdownStepItem';
import SearchVariablesDropdownStepSubItem from '@/workflow/search-variables/components/SearchVariablesDropdownStepSubItem';
import { SEARCH_VARIABLES_DROPDOWN_ID } from '@/workflow/search-variables/constants/SearchVariablesDropdownId';
import { useAvailableVariablesInWorkflowStep } from '@/workflow/search-variables/hooks/useAvailableVariablesInWorkflowStep';
import { StepOutputSchema } from '@/workflow/search-variables/types/StepOutputSchema';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { Editor } from '@tiptap/react';
import { useState } from 'react';
import { IconVariablePlus } from 'twenty-ui';
const StyledDropdownVariableButtonContainer = styled(
StyledDropdownButtonContainer,
)<{ transparentBackground?: boolean; disabled?: boolean }>`
background-color: ${({ theme, transparentBackground }) =>
transparentBackground
? 'transparent'
: theme.background.transparent.lighter};
color: ${({ theme }) => theme.font.color.tertiary};
padding: ${({ theme }) => theme.spacing(2)};
:hover {
cursor: ${({ disabled }) => (disabled ? 'not-allowed' : 'pointer')};
}
`;
const SearchVariablesDropdown = ({
inputId,
editor,
disabled,
}: {
inputId: string;
editor: Editor;
disabled?: boolean;
}) => {
const theme = useTheme();
const dropdownId = `${SEARCH_VARIABLES_DROPDOWN_ID}-${inputId}`;
const { isDropdownOpen } = useDropdown(dropdownId);
const availableVariablesInWorkflowStep =
useAvailableVariablesInWorkflowStep();
const initialStep =
availableVariablesInWorkflowStep.length === 1
? availableVariablesInWorkflowStep[0]
: undefined;
const [selectedStep, setSelectedStep] = useState<
StepOutputSchema | undefined
>(initialStep);
const insertVariableTag = (variable: string) => {
editor.commands.insertVariableTag(variable);
};
const handleStepSelect = (stepId: string) => {
setSelectedStep(
availableVariablesInWorkflowStep.find((step) => step.id === stepId),
);
};
const handleSubItemSelect = (subItem: string) => {
insertVariableTag(subItem);
};
const handleBack = () => {
setSelectedStep(undefined);
};
if (disabled === true) {
return (
<StyledDropdownVariableButtonContainer
isUnfolded={isDropdownOpen}
disabled={disabled}
transparentBackground
>
<IconVariablePlus
size={theme.icon.size.sm}
color={theme.font.color.light}
/>
</StyledDropdownVariableButtonContainer>
);
}
return (
<Dropdown
dropdownMenuWidth={320}
dropdownId={dropdownId}
dropdownHotkeyScope={{
scope: dropdownId,
}}
clickableComponent={
<StyledDropdownVariableButtonContainer
isUnfolded={isDropdownOpen}
disabled={disabled}
transparentBackground
>
<IconVariablePlus size={theme.icon.size.sm} />
</StyledDropdownVariableButtonContainer>
}
dropdownComponents={
<DropdownMenuItemsContainer hasMaxHeight>
{selectedStep ? (
<SearchVariablesDropdownStepSubItem
step={selectedStep}
onSelect={handleSubItemSelect}
onBack={handleBack}
/>
) : (
<SearchVariablesDropdownStepItem
steps={availableVariablesInWorkflowStep}
onSelect={handleStepSelect}
/>
)}
</DropdownMenuItemsContainer>
}
dropdownPlacement="bottom-end"
dropdownOffset={{ x: 0, y: 4 }}
/>
);
};
export default SearchVariablesDropdown;