diff --git a/packages/twenty-front/src/modules/workflow/workflow-trigger/components/WorkflowEditTriggerDatabaseEventForm.tsx b/packages/twenty-front/src/modules/workflow/workflow-trigger/components/WorkflowEditTriggerDatabaseEventForm.tsx index 68415b846..db8630a1c 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-trigger/components/WorkflowEditTriggerDatabaseEventForm.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-trigger/components/WorkflowEditTriggerDatabaseEventForm.tsx @@ -1,5 +1,13 @@ import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems'; -import { Select } from '@/ui/input/components/Select'; +import { SelectControl } from '@/ui/input/components/SelectControl'; +import { SelectHotkeyScope } from '@/ui/input/types/SelectHotkeyScope'; +import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; +import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; +import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; +import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput'; +import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator'; +import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { WorkflowDatabaseEventTrigger } from '@/workflow/types/Workflow'; import { splitWorkflowTriggerEventName } from '@/workflow/utils/splitWorkflowTriggerEventName'; import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody'; @@ -7,8 +15,34 @@ import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/Workflo import { getTriggerIcon } from '@/workflow/workflow-trigger/utils/getTriggerIcon'; import { getTriggerDefaultLabel } from '@/workflow/workflow-trigger/utils/getTriggerLabel'; import { useTheme } from '@emotion/react'; -import { isDefined } from 'twenty-shared/utils'; -import { SelectOption, useIcons } from 'twenty-ui'; +import styled from '@emotion/styled'; +import { Trans } from '@lingui/react/macro'; +import { useCallback, useMemo, useState } from 'react'; +import { IconChevronLeft, IconSettings, MenuItem, useIcons } from 'twenty-ui'; + +const StyledLabel = styled.span` + color: ${({ theme }) => theme.font.color.light}; + display: block; + font-size: ${({ theme }) => theme.font.size.xs}; + font-weight: ${({ theme }) => theme.font.weight.semiBold}; + margin-bottom: ${({ theme }) => theme.spacing(1)}; +`; + +const StyledContainer = styled.div<{ fullWidth?: boolean }>` + width: ${({ fullWidth }) => (fullWidth ? '100%' : 'auto')}; +`; + +const DEFAULT_SELECTED_OPTION = { label: 'Select an option', value: '' }; + +const filterOptionsBySearch = ( + options: T[], + searchValue: string, +): T[] => { + if (!searchValue) return options; + return options.filter((option) => + option.label.toLowerCase().includes(searchValue.toLowerCase()), + ); +}; type WorkflowEditTriggerDatabaseEventFormProps = { trigger: WorkflowDatabaseEventTrigger; @@ -29,20 +63,47 @@ export const WorkflowEditTriggerDatabaseEventForm = ({ }: WorkflowEditTriggerDatabaseEventFormProps) => { const theme = useTheme(); const { getIcon } = useIcons(); + const [searchInputValue, setSearchInputValue] = useState(''); + const [isSystemObjectsOpen, setIsSystemObjectsOpen] = useState(false); + const { closeDropdown } = useDropdown('workflow-edit-trigger-record-type'); - const { activeObjectMetadataItems } = useFilteredObjectMetadataItems(); + const { objectMetadataItems } = useFilteredObjectMetadataItems(); const triggerEvent = splitWorkflowTriggerEventName( trigger.settings.eventName, ); - const availableMetadata: Array> = - activeObjectMetadataItems.map((item) => ({ + const regularObjects = objectMetadataItems + .filter((item) => item.isActive && !item.isSystem) + .map((item) => ({ label: item.labelPlural, value: item.nameSingular, Icon: getIcon(item.icon), })); + const systemObjects = objectMetadataItems + .filter((item) => item.isActive && item.isSystem) + .map((item) => ({ + label: item.labelPlural, + value: item.nameSingular, + Icon: getIcon(item.icon), + })); + + const selectedOption = + [...regularObjects, ...systemObjects].find( + (option) => option.value === triggerEvent?.objectType, + ) || DEFAULT_SELECTED_OPTION; + + const filteredRegularObjects = useMemo( + () => filterOptionsBySearch(regularObjects, searchInputValue), + [regularObjects, searchInputValue], + ); + + const filteredSystemObjects = useMemo( + () => filterOptionsBySearch(systemObjects, searchInputValue), + [systemObjects, searchInputValue], + ); + const defaultLabel = getTriggerDefaultLabel({ type: 'DATABASE_EVENT', @@ -54,10 +115,40 @@ export const WorkflowEditTriggerDatabaseEventForm = ({ eventName: triggerEvent.event, }); - const headerTitle = isDefined(trigger.name) ? trigger.name : defaultLabel; - const headerType = `Trigger ยท ${defaultLabel}`; + const handleOptionClick = (value: string) => { + if (triggerOptions.readonly === true) { + return; + } + + triggerOptions.onTriggerUpdate({ + ...trigger, + settings: { + ...trigger.settings, + eventName: `${value}.${triggerEvent.event}`, + }, + }); + closeDropdown(); + }; + + const handleSystemObjectsClick = () => { + setIsSystemObjectsOpen(true); + setSearchInputValue(''); + }; + + const handleBack = () => { + setIsSystemObjectsOpen(false); + setSearchInputValue(''); + }; + + const handleSearchInputChange = useCallback( + (event: React.ChangeEvent) => { + setSearchInputValue(event.target.value); + }, + [], + ); + return ( <> -