diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersDropdownContent.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersDropdownContent.tsx index 6d33a4082..43f9e4faf 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersDropdownContent.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersDropdownContent.tsx @@ -5,15 +5,10 @@ import { ObjectFilterOperandSelectAndInput } from '@/object-record/object-filter import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFilterIsSelectedComponentState'; import { objectFilterDropdownIsSelectingCompositeFieldComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownIsSelectingCompositeFieldComponentState'; import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2'; -import styled from '@emotion/styled'; import { useRecoilValue } from 'recoil'; import { MultipleFiltersDropdownFilterOnFilterChangedEffect } from './MultipleFiltersDropdownFilterOnFilterChangedEffect'; import { ObjectFilterDropdownFilterSelect } from './ObjectFilterDropdownFilterSelect'; -const StyledContainer = styled.div` - position: relative; -`; - type MultipleFiltersDropdownContentProps = { filterDropdownId?: string; }; @@ -46,7 +41,7 @@ export const MultipleFiltersDropdownContent = ({ const shoudShowFilterInput = objectFilterDropdownFilterIsSelected; return ( - + <> {shoudShowFilterInput ? ( - + ); }; diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterInput.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterInput.tsx index 98b57174b..050fb9021 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterInput.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterInput.tsx @@ -28,8 +28,13 @@ export const ObjectFilterDropdownFilterInput = ({ const { filterDefinitionUsedInDropdownState, selectedOperandInDropdownState, + isObjectFilterDropdownOperandSelectUnfoldedState, } = useFilterDropdown({ filterDropdownId }); + const isObjectFilterDropdownOperandSelectUnfolded = useRecoilValue( + isObjectFilterDropdownOperandSelectUnfoldedState, + ); + const filterDefinitionUsedInDropdown = useRecoilValue( filterDefinitionUsedInDropdownState, ); @@ -53,7 +58,9 @@ export const ObjectFilterDropdownFilterInput = ({ ViewFilterOperand.IsRelative, ].includes(selectedOperandInDropdown); - if (!isDefined(filterDefinitionUsedInDropdown)) { + const shouldHide = isObjectFilterDropdownOperandSelectUnfolded; + + if (shouldHide || !isDefined(filterDefinitionUsedInDropdown)) { return null; } diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterOperandSelect.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterOperandSelect.tsx index b603f0813..4aad6ec39 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterOperandSelect.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterOperandSelect.tsx @@ -8,9 +8,7 @@ const StyledOperandSelectContainer = styled.div` background: ${({ theme }) => theme.background.secondary}; box-shadow: ${({ theme }) => theme.boxShadow.light}; border-radius: ${({ theme }) => theme.border.radius.md}; - left: 10px; - position: absolute; - top: 10px; + width: 100%; z-index: 1000; `; diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelect.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelect.tsx index f33bbf38d..7b05d5874 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelect.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelect.tsx @@ -16,6 +16,7 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM import { SelectableItem } from '@/ui/layout/selectable-list/components/SelectableItem'; import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList'; import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList'; +import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useGetCurrentView } from '@/views/hooks/useGetCurrentView'; import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState'; @@ -35,7 +36,7 @@ export const StyledInput = styled.input` margin: 0; outline: none; padding: ${({ theme }) => theme.spacing(2)}; - height: 19px; + min-height: 19px; font-family: inherit; font-size: ${({ theme }) => theme.font.size.sm}; @@ -160,43 +161,45 @@ export const ObjectFilterDropdownFilterSelect = ({ setObjectFilterDropdownSearchInput(event.target.value) } /> - - - {visibleColumnsFilterDefinitions.map( - (visibleFilterDefinition, index) => ( - - - - ), - )} - - {shoudShowSeparator && } - - {hiddenColumnsFilterDefinitions.map( - (hiddenFilterDefinition, index) => ( - - - - ), - )} - - - {shouldShowAdvancedFilterButton && } + + + + {visibleColumnsFilterDefinitions.map( + (visibleFilterDefinition, index) => ( + + + + ), + )} + + {shoudShowSeparator && } + + {hiddenColumnsFilterDefinitions.map( + (hiddenFilterDefinition, index) => ( + + + + ), + )} + + + {shouldShowAdvancedFilterButton && } + ); }; diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandButton.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandButton.tsx index 3931c7654..1e21d36b1 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandButton.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandButton.tsx @@ -10,17 +10,28 @@ export const ObjectFilterDropdownOperandButton = () => { const { selectedOperandInDropdownState, setIsObjectFilterDropdownOperandSelectUnfolded, + isObjectFilterDropdownOperandSelectUnfoldedState, } = useFilterDropdown(); const selectedOperandInDropdown = useRecoilValue( selectedOperandInDropdownState, ); + const isObjectFilterDropdownOperandSelectUnfolded = useRecoilValue( + isObjectFilterDropdownOperandSelectUnfoldedState, + ); + + const handleButtonClick = () => { + setIsObjectFilterDropdownOperandSelectUnfolded( + !isObjectFilterDropdownOperandSelectUnfolded, + ); + }; + return ( setIsObjectFilterDropdownOperandSelectUnfolded(true)} + onClick={handleButtonClick} > {getOperandLabel(selectedOperandInDropdown)} diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOptionSelect.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOptionSelect.tsx index b2e2535ca..b0c1ff877 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOptionSelect.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOptionSelect.tsx @@ -16,6 +16,7 @@ import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectab import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; import { MenuItemMultiSelect } from '@/ui/navigation/menu-item/components/MenuItemMultiSelect'; import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; +import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper'; import { isDefined } from '~/utils/isDefined'; export const EMPTY_FILTER_VALUE = ''; @@ -162,22 +163,24 @@ export const ObjectFilterDropdownOptionSelect = () => { } }} > - - {optionsInDropdown?.map((option) => ( - - handleMultipleOptionSelectChange(option, selected) - } - text={option.label} - color={option.color} - className="" - /> - ))} - - {showNoResult && } + + + {optionsInDropdown?.map((option) => ( + + handleMultipleOptionSelectChange(option, selected) + } + text={option.label} + color={option.color} + className="" + /> + ))} + + {showNoResult && } + ); }; diff --git a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/components/ObjectSortDropdownButton.tsx b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/components/ObjectSortDropdownButton.tsx index f1e399c1a..4013db110 100644 --- a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/components/ObjectSortDropdownButton.tsx +++ b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/components/ObjectSortDropdownButton.tsx @@ -15,6 +15,7 @@ import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/Styl import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope'; +import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper'; import { useContext } from 'react'; import { SORT_DIRECTIONS } from '../types/SortDirection'; @@ -42,17 +43,13 @@ export const StyledInput = styled.input` } `; -const StyledContainer = styled.div` - position: relative; -`; - const StyledSelectedSortDirectionContainer = styled.div` background: ${({ theme }) => theme.background.secondary}; box-shadow: ${({ theme }) => theme.boxShadow.light}; border-radius: ${({ theme }) => theme.border.radius.md}; - left: 10px; + position: absolute; - top: 10px; + top: 32px; width: 100%; z-index: 1000; `; @@ -166,21 +163,23 @@ export const ObjectSortDropdownButton = ({ )} - - setIsSortDirectionMenuUnfolded(true)} - > - {selectedSortDirection === 'asc' ? 'Ascending' : 'Descending'} - - - setObjectSortDropdownSearchInput(event.target.value) - } - /> + + setIsSortDirectionMenuUnfolded(!isSortDirectionMenuUnfolded) + } + > + {selectedSortDirection === 'asc' ? 'Ascending' : 'Descending'} + + + setObjectSortDropdownSearchInput(event.target.value) + } + /> + {visibleColumnsSortDefinitions.map( (visibleSortDefinition, index) => ( @@ -214,7 +213,7 @@ export const ObjectSortDropdownButton = ({ ), )} - + } onClose={handleDropdownButtonClose} diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/MultiItemFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/MultiItemFieldInput.tsx index 0193e75da..c23b31bc2 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/MultiItemFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/MultiItemFieldInput.tsx @@ -21,7 +21,6 @@ import { turnIntoEmptyStringIfWhitespacesOnly } from '~/utils/string/turnIntoEmp const StyledDropdownMenu = styled(DropdownMenu)` left: -1px; - position: absolute; top: -1px; `; @@ -46,6 +45,7 @@ type MultiItemFieldInputProps = { }; // Todo: the API of this component does not look healthy: we have renderInput, renderItem, formatInput, ... +// This should be refactored with a hook instead that exposes those events in a context around this component and its children. export const MultiItemFieldInput = ({ items, onPersist, diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/MultiItemFieldMenuItem.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/MultiItemFieldMenuItem.tsx index 383b47121..150efe882 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/MultiItemFieldMenuItem.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/MultiItemFieldMenuItem.tsx @@ -1,14 +1,11 @@ -import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; -import styled from '@emotion/styled'; -import { useEffect, useState } from 'react'; +import { MenuItemWithOptionDropdown } from '@/ui/navigation/menu-item/components/MenuItemWithOptionDropdown'; +import { useState } from 'react'; import { IconBookmark, IconBookmarkPlus, - IconComponent, - IconDotsVertical, IconPencil, IconTrash, } from 'twenty-ui'; @@ -24,12 +21,6 @@ type MultiItemFieldMenuItemProps = { hasPrimaryButton?: boolean; }; -const StyledIconBookmark = styled(IconBookmark)` - color: ${({ theme }) => theme.font.color.light}; - height: ${({ theme }) => theme.icon.size.sm}px; - width: ${({ theme }) => theme.icon.size.sm}px; -`; - export const MultiItemFieldMenuItem = ({ dropdownId, isPrimary, @@ -47,66 +38,51 @@ export const MultiItemFieldMenuItem = ({ const handleMouseLeave = () => setIsHovered(false); const handleDeleteClick = () => { + closeDropdown(); setIsHovered(false); onDelete?.(); }; - useEffect(() => { - if (isDropdownOpen) { - return () => closeDropdown(); - } - }, [closeDropdown, isDropdownOpen]); + const handleSetAsPrimaryClick = () => { + closeDropdown(); + onSetAsPrimary?.(); + }; + + const handleEditClick = () => { + closeDropdown(); + onEdit?.(); + }; return ( - } isIconDisplayedOnHoverOnly={!isPrimary && !isDropdownOpen} - iconButtons={[ - { - Wrapper: isHovered - ? ({ iconButton }) => ( - - {hasPrimaryButton && !isPrimary && ( - - )} - - - - } - /> - ) - : undefined, - Icon: - isPrimary && !isHovered - ? (StyledIconBookmark as IconComponent) - : IconDotsVertical, - accent: 'tertiary', - onClick: isHovered ? () => {} : undefined, - }, - ]} + RightIcon={isHovered ? null : IconBookmark} + dropdownId={dropdownId} + dropdownContent={ + + {hasPrimaryButton && !isPrimary && ( + + )} + + + + } /> ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdownContent.tsx b/packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdownContent.tsx index 0375ab340..4fa2394d6 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdownContent.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdownContent.tsx @@ -40,6 +40,7 @@ import { MenuItemNavigate } from '@/ui/navigation/menu-item/components/MenuItemN import { MenuItemToggle } from '@/ui/navigation/menu-item/components/MenuItemToggle'; import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState'; import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; +import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper'; import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFieldsVisibilityDropdownSection'; import { ViewGroupsVisibilityDropdownSection } from '@/views/components/ViewGroupsVisibilityDropdownSection'; import { useGetCurrentView } from '@/views/hooks/useGetCurrentView'; @@ -259,15 +260,17 @@ export const RecordIndexOptionsDropdownContent = ({ Fields - + + +