[Workflow] Add search in variable dropdown (#8479)
- fix Icon variable Plus - add search input - fix dropdown height ## Before  ## After 
This commit is contained in:
@ -15,9 +15,10 @@ const StyledHeader = styled.li`
|
||||
border-top-right-radius: ${({ theme }) => theme.border.radius.sm};
|
||||
border-bottom: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
|
||||
padding: ${({ theme }) => theme.spacing(1)};
|
||||
padding: ${({ theme }) => theme.spacing(1)} 0;
|
||||
|
||||
user-select: none;
|
||||
width: inherit;
|
||||
|
||||
&:hover {
|
||||
background: ${({ theme, onClick }) =>
|
||||
|
||||
@ -3,12 +3,17 @@ import styled from '@emotion/styled';
|
||||
type StyledDropdownButtonProps = {
|
||||
isUnfolded: boolean;
|
||||
isActive?: boolean;
|
||||
transparentBackground?: boolean;
|
||||
};
|
||||
|
||||
export const StyledDropdownButtonContainer = styled.div<StyledDropdownButtonProps>`
|
||||
align-items: center;
|
||||
background: ${({ theme, isUnfolded }) =>
|
||||
isUnfolded ? theme.background.transparent.light : theme.background.primary};
|
||||
background: ${({ theme, isUnfolded, transparentBackground }) =>
|
||||
transparentBackground
|
||||
? 'none'
|
||||
: isUnfolded
|
||||
? theme.background.transparent.light
|
||||
: theme.background.primary};
|
||||
border-radius: ${({ theme }) => theme.border.radius.sm};
|
||||
color: ${({ isActive, theme }) =>
|
||||
isActive ? theme.color.blue : theme.font.color.secondary};
|
||||
@ -22,9 +27,11 @@ export const StyledDropdownButtonContainer = styled.div<StyledDropdownButtonProp
|
||||
user-select: none;
|
||||
|
||||
&:hover {
|
||||
background: ${({ theme, isUnfolded }) =>
|
||||
isUnfolded
|
||||
? theme.background.transparent.medium
|
||||
: theme.background.transparent.light};
|
||||
background: ${({ theme, isUnfolded, transparentBackground }) =>
|
||||
transparentBackground
|
||||
? 'transparent'
|
||||
: isUnfolded
|
||||
? theme.background.transparent.medium
|
||||
: theme.background.transparent.light};
|
||||
}
|
||||
`;
|
||||
|
||||
@ -11,15 +11,17 @@ import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { Editor } from '@tiptap/react';
|
||||
import { useState } from 'react';
|
||||
import { IconVariable } from 'twenty-ui';
|
||||
import { IconVariablePlus } from 'twenty-ui';
|
||||
|
||||
const StyledDropdownVariableButtonContainer = styled(
|
||||
StyledDropdownButtonContainer,
|
||||
)`
|
||||
background-color: ${({ theme }) => theme.background.transparent.lighter};
|
||||
)<{ transparentBackground?: boolean }>`
|
||||
background-color: ${({ theme, transparentBackground }) =>
|
||||
transparentBackground
|
||||
? 'transparent'
|
||||
: theme.background.transparent.lighter};
|
||||
color: ${({ theme }) => theme.font.color.tertiary};
|
||||
padding: ${({ theme }) => theme.spacing(0)};
|
||||
margin: ${({ theme }) => theme.spacing(2)};
|
||||
padding: ${({ theme }) => theme.spacing(2)};
|
||||
`;
|
||||
|
||||
const SearchVariablesDropdown = ({
|
||||
@ -65,12 +67,15 @@ const SearchVariablesDropdown = ({
|
||||
scope: dropdownId,
|
||||
}}
|
||||
clickableComponent={
|
||||
<StyledDropdownVariableButtonContainer isUnfolded={isDropdownOpen}>
|
||||
<IconVariable size={theme.icon.size.sm} />
|
||||
<StyledDropdownVariableButtonContainer
|
||||
isUnfolded={isDropdownOpen}
|
||||
transparentBackground
|
||||
>
|
||||
<IconVariablePlus size={theme.icon.size.sm} />
|
||||
</StyledDropdownVariableButtonContainer>
|
||||
}
|
||||
dropdownComponents={
|
||||
<DropdownMenuItemsContainer>
|
||||
<DropdownMenuItemsContainer hasMaxHeight>
|
||||
{selectedStep ? (
|
||||
<SearchVariablesDropdownStepSubItem
|
||||
step={selectedStep}
|
||||
|
||||
@ -3,6 +3,7 @@ import { StepOutputSchema } from '@/workflow/search-variables/types/StepOutputSc
|
||||
import { isObject } from '@sniptt/guards';
|
||||
import { useState } from 'react';
|
||||
import { IconChevronLeft, MenuItemSelect } from 'twenty-ui';
|
||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
||||
|
||||
type SearchVariablesDropdownStepSubItemProps = {
|
||||
step: StepOutputSchema;
|
||||
@ -16,6 +17,7 @@ const SearchVariablesDropdownStepSubItem = ({
|
||||
onBack,
|
||||
}: SearchVariablesDropdownStepSubItemProps) => {
|
||||
const [currentPath, setCurrentPath] = useState<string[]>([]);
|
||||
const [searchInputValue, setSearchInputValue] = useState('');
|
||||
|
||||
const getSelectedObject = () => {
|
||||
let selected = step.outputSchema;
|
||||
@ -30,6 +32,7 @@ const SearchVariablesDropdownStepSubItem = ({
|
||||
|
||||
if (isObject(selectedObject[key])) {
|
||||
setCurrentPath([...currentPath, key]);
|
||||
setSearchInputValue('');
|
||||
} else {
|
||||
onSelect(`{{${step.id}.${[...currentPath, key].join('.')}}}`);
|
||||
}
|
||||
@ -45,12 +48,25 @@ const SearchVariablesDropdownStepSubItem = ({
|
||||
|
||||
const headerLabel = currentPath.length === 0 ? step.name : currentPath.at(-1);
|
||||
|
||||
const options = Object.entries(getSelectedObject());
|
||||
|
||||
const filteredOptions = searchInputValue
|
||||
? options.filter(([key]) =>
|
||||
key.toLowerCase().includes(searchInputValue.toLowerCase()),
|
||||
)
|
||||
: options;
|
||||
|
||||
return (
|
||||
<>
|
||||
<DropdownMenuHeader StartIcon={IconChevronLeft} onClick={goBack}>
|
||||
{headerLabel}
|
||||
</DropdownMenuHeader>
|
||||
{Object.entries(getSelectedObject()).map(([key, value]) => (
|
||||
<DropdownMenuSearchInput
|
||||
autoFocus
|
||||
value={searchInputValue}
|
||||
onChange={(event) => setSearchInputValue(event.target.value)}
|
||||
/>
|
||||
{filteredOptions.map(([key, value]) => (
|
||||
<MenuItemSelect
|
||||
key={key}
|
||||
selected={false}
|
||||
|
||||
@ -231,7 +231,7 @@ export {
|
||||
IconUser,
|
||||
IconUserCircle,
|
||||
IconUsers,
|
||||
IconVariable,
|
||||
IconVariablePlus,
|
||||
IconVideo,
|
||||
IconWand,
|
||||
IconWorld,
|
||||
|
||||
Reference in New Issue
Block a user