From 606098fef6704427c5ce40b66e207489c0334ef4 Mon Sep 17 00:00:00 2001 From: Antoine Moreaux Date: Tue, 18 Mar 2025 08:19:22 +0100 Subject: [PATCH] refacto(twenty-front): improve DropdownMenuHeader api (#10961) --- ...pdownFilterSelectCompositeFieldSubMenu.tsx | 9 +++- .../ObjectOptionsDropdownFieldsContent.tsx | 9 +++- ...jectOptionsDropdownHiddenFieldsContent.tsx | 9 +++- ...tionsDropdownHiddenRecordGroupsContent.tsx | 9 +++- .../ObjectOptionsDropdownLayoutContent.tsx | 9 +++- ...jectOptionsDropdownLayoutOpenInContent.tsx | 9 +++- .../ObjectOptionsDropdownMenuContent.tsx | 7 ++- ...ptionsDropdownRecordGroupFieldsContent.tsx | 15 ++++-- ...tOptionsDropdownRecordGroupSortContent.tsx | 9 +++- ...jectOptionsDropdownRecordGroupsContent.tsx | 9 +++- .../components/ObjectSortDropdownButton.tsx | 5 +- ...mnHeaderAggregateDropdownFieldsContent.tsx | 15 ++++-- ...nHeaderAggregateDropdownOptionsContent.tsx | 9 +++- ...eColumnAggregateDropdownSubmenuContent.tsx | 9 +++- .../DropdownMenuHeader/DropdownMenuHeader.tsx | 53 ++++--------------- ...sx => DropdownMenuHeaderLeftComponent.tsx} | 16 +++--- .../DropdownMenuHeaderWithDropdownMenu.tsx | 34 ------------ .../__stories__/DropdownMenu.stories.tsx | 7 ++- .../DropdownMenuHeader.stories.tsx | 18 +++---- .../MultiWorkspaceDropdownButton.tsx | 2 +- ...ltiWorkspaceDropdownClickableComponent.tsx | 2 +- ...ultiWorkspaceDropdownDefaultComponents.tsx | 15 ++++-- ...MultiWorkspaceDropdownThemesComponents.tsx | 9 +++- ...kspaceDropdownWorkspacesListComponents.tsx | 9 +++- .../ViewPickerContentCreateMode.tsx | 7 ++- .../components/ViewPickerContentEditMode.tsx | 9 +++- .../WorkflowVariablesDropdownFieldItems.tsx | 9 +++- .../WorkflowVariablesDropdownObjectItems.tsx | 10 +++- ...flowVariablesDropdownWorkflowStepItems.tsx | 10 +++- 29 files changed, 194 insertions(+), 148 deletions(-) rename packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuHeader/internal/{DropdownMenuHeaderStartIcon.tsx => DropdownMenuHeaderLeftComponent.tsx} (79%) delete mode 100644 packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderWithDropdownMenu.tsx diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectCompositeFieldSubMenu.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectCompositeFieldSubMenu.tsx index 98ec5fd97..cc4456e4a 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectCompositeFieldSubMenu.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectCompositeFieldSubMenu.tsx @@ -28,6 +28,7 @@ import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-sta import { useState } from 'react'; import { isDefined } from 'twenty-shared'; import { IconApps, IconChevronLeft, MenuItem, useIcons } from 'twenty-ui'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; export const ObjectFilterDropdownFilterSelectCompositeFieldSubMenu = () => { const [searchText] = useState(''); @@ -187,8 +188,12 @@ export const ObjectFilterDropdownFilterSelectCompositeFieldSubMenu = () => { return ( <> + } > {getFilterableFieldTypeLabel(objectFilterDropdownSubMenuFieldType)} diff --git a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownFieldsContent.tsx b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownFieldsContent.tsx index 0c68109fd..a75fc3563 100644 --- a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownFieldsContent.tsx +++ b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownFieldsContent.tsx @@ -9,6 +9,7 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFieldsVisibilityDropdownSection'; import { ViewType } from '@/views/types/ViewType'; import { useLingui } from '@lingui/react/macro'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; export const ObjectOptionsDropdownFieldsContent = () => { const { t } = useLingui(); @@ -52,8 +53,12 @@ export const ObjectOptionsDropdownFieldsContent = () => { return ( <> + } > {t`Fields`} diff --git a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownHiddenFieldsContent.tsx b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownHiddenFieldsContent.tsx index 07d595ae7..3112823ae 100644 --- a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownHiddenFieldsContent.tsx +++ b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownHiddenFieldsContent.tsx @@ -21,6 +21,7 @@ import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFiel import { ViewType } from '@/views/types/ViewType'; import { useLingui } from '@lingui/react/macro'; import { getSettingsPath } from '~/utils/navigation/getSettingsPath'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; export const ObjectOptionsDropdownHiddenFieldsContent = () => { const { t } = useLingui(); @@ -66,8 +67,12 @@ export const ObjectOptionsDropdownHiddenFieldsContent = () => { return ( <> onContentChange('fields')} + StartComponent={ + onContentChange('fields')} + Icon={IconChevronLeft} + /> + } > {t`Hidden Fields`} diff --git a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownHiddenRecordGroupsContent.tsx b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownHiddenRecordGroupsContent.tsx index c527bfc9a..e663000c6 100644 --- a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownHiddenRecordGroupsContent.tsx +++ b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownHiddenRecordGroupsContent.tsx @@ -23,6 +23,7 @@ import { useLingui } from '@lingui/react/macro'; import { useLocation } from 'react-router-dom'; import { useSetRecoilState } from 'recoil'; import { getSettingsPath } from '~/utils/navigation/getSettingsPath'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; export const ObjectOptionsDropdownHiddenRecordGroupsContent = () => { const { t } = useLingui(); @@ -74,8 +75,12 @@ export const ObjectOptionsDropdownHiddenRecordGroupsContent = () => { <> onContentChange('recordGroups')} + StartComponent={ + onContentChange('recordGroups')} + Icon={IconChevronLeft} + /> + } > Hidden {recordGroupFieldMetadata?.label} diff --git a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx index fca6a1a3d..af1db6e8f 100644 --- a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx +++ b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx @@ -17,6 +17,7 @@ import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType'; import { ViewType } from '@/views/types/ViewType'; import { useLingui } from '@lingui/react/macro'; import { useRecoilValue } from 'recoil'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; export const ObjectOptionsDropdownLayoutContent = () => { const { t } = useLingui(); @@ -42,8 +43,12 @@ export const ObjectOptionsDropdownLayoutContent = () => { return ( <> + } > {t`Layout`} diff --git a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutOpenInContent.tsx b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutOpenInContent.tsx index 992e5e5d5..d87d07752 100644 --- a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutOpenInContent.tsx +++ b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutOpenInContent.tsx @@ -14,6 +14,7 @@ import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly'; import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType'; import { t } from '@lingui/core/macro'; import { useRecoilValue } from 'recoil'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; export const ObjectOptionsDropdownLayoutOpenInContent = () => { const { onContentChange } = useOptionsDropdown(); @@ -24,8 +25,12 @@ export const ObjectOptionsDropdownLayoutOpenInContent = () => { return ( <> onContentChange('layout')} + StartComponent={ + onContentChange('layout')} + Icon={IconChevronLeft} + /> + } > {t`Open in`} diff --git a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownMenuContent.tsx b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownMenuContent.tsx index 689a88aaf..e4515a678 100644 --- a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownMenuContent.tsx +++ b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownMenuContent.tsx @@ -31,6 +31,7 @@ import { useDeleteViewFromCurrentState } from '@/views/view-picker/hooks/useDele import { viewPickerReferenceViewIdComponentState } from '@/views/view-picker/states/viewPickerReferenceViewIdComponentState'; import { useTheme } from '@emotion/react'; import { useLingui } from '@lingui/react/macro'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; export const ObjectOptionsDropdownMenuContent = () => { const { t } = useLingui(); @@ -82,7 +83,11 @@ export const ObjectOptionsDropdownMenuContent = () => { return ( <> - + + } + > {currentView?.name} diff --git a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownRecordGroupFieldsContent.tsx b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownRecordGroupFieldsContent.tsx index cd66ee63c..f046de355 100644 --- a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownRecordGroupFieldsContent.tsx +++ b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownRecordGroupFieldsContent.tsx @@ -30,6 +30,7 @@ import { useSetRecoilState } from 'recoil'; import { isDefined } from 'twenty-shared'; import { FieldMetadataType } from '~/generated-metadata/graphql'; import { getSettingsPath } from '~/utils/navigation/getSettingsPath'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; export const ObjectOptionsDropdownRecordGroupFieldsContent = () => { const { t } = useLingui(); @@ -106,11 +107,15 @@ export const ObjectOptionsDropdownRecordGroupFieldsContent = () => { return ( <> - isDefined(recordGroupFieldMetadata) - ? onContentChange('recordGroups') - : resetContent() + StartComponent={ + + isDefined(recordGroupFieldMetadata) + ? onContentChange('recordGroups') + : resetContent() + } + Icon={IconChevronLeft} + /> } > Group by diff --git a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownRecordGroupSortContent.tsx b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownRecordGroupSortContent.tsx index 305c09e1e..2ae2c1a3c 100644 --- a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownRecordGroupSortContent.tsx +++ b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownRecordGroupSortContent.tsx @@ -15,6 +15,7 @@ import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenu import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; export const ObjectOptionsDropdownRecordGroupSortContent = () => { const { currentContentId, onContentChange } = useOptionsDropdown(); @@ -43,8 +44,12 @@ export const ObjectOptionsDropdownRecordGroupSortContent = () => { return ( <> onContentChange('recordGroups')} + StartComponent={ + onContentChange('recordGroups')} + Icon={IconChevronLeft} + /> + } > Sort diff --git a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownRecordGroupsContent.tsx b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownRecordGroupsContent.tsx index aded779c2..337d0d20c 100644 --- a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownRecordGroupsContent.tsx +++ b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownRecordGroupsContent.tsx @@ -27,6 +27,7 @@ import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/component- import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly'; import { useLingui } from '@lingui/react/macro'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; export const ObjectOptionsDropdownRecordGroupsContent = () => { const { t } = useLingui(); @@ -89,8 +90,12 @@ export const ObjectOptionsDropdownRecordGroupsContent = () => { return ( <> + } > Group by 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 52c6d4455..c623de97b 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 @@ -32,6 +32,7 @@ import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-sta import { Trans, useLingui } from '@lingui/react/macro'; import { useRecoilValue } from 'recoil'; import { v4 } from 'uuid'; +import { useTheme } from '@emotion/react'; export const StyledInput = styled.input` background: transparent; @@ -187,6 +188,8 @@ export const ObjectSortDropdownButton = ({ const { t } = useLingui(); + const theme = useTheme(); + return ( )} setIsRecordSortDirectionMenuUnfolded( !isRecordSortDirectionMenuUnfolded, ) } + EndComponent={} > {selectedRecordSortDirection === 'asc' ? t`Ascending` diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownFieldsContent.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownFieldsContent.tsx index 3ed222bc3..6c0d3ebb9 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownFieldsContent.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownFieldsContent.tsx @@ -17,6 +17,7 @@ import { MenuItem, useIcons, } from 'twenty-ui'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; export const RecordBoardColumnHeaderAggregateDropdownFieldsContent = () => { const { @@ -49,11 +50,15 @@ export const RecordBoardColumnHeaderAggregateDropdownFieldsContent = () => { return ( <> - previousContentId - ? onContentChange(previousContentId) - : resetContent() + StartComponent={ + + previousContentId + ? onContentChange(previousContentId) + : resetContent() + } + Icon={IconChevronLeft} + /> } > {getAggregateOperationLabel(aggregateOperation)} diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownOptionsContent.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownOptionsContent.tsx index 51676441e..d55e743bf 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownOptionsContent.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownOptionsContent.tsx @@ -21,6 +21,7 @@ import isEmpty from 'lodash.isempty'; import { useRecoilValue } from 'recoil'; import { Key } from 'ts-key-enum'; import { IconCheck, IconChevronLeft } from 'twenty-ui'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; export const RecordBoardColumnHeaderAggregateDropdownOptionsContent = ({ availableAggregations, @@ -59,8 +60,12 @@ export const RecordBoardColumnHeaderAggregateDropdownOptionsContent = ({ return ( <> + } > {title} diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateDropdownSubmenuContent.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateDropdownSubmenuContent.tsx index 3beaed4af..d28f70e70 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateDropdownSubmenuContent.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateDropdownSubmenuContent.tsx @@ -9,6 +9,7 @@ import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; import { useContext } from 'react'; import { Key } from 'ts-key-enum'; import { IconChevronLeft } from 'twenty-ui'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; export const RecordTableColumnAggregateFooterDropdownSubmenuContent = ({ aggregateOperations, @@ -33,8 +34,12 @@ export const RecordTableColumnAggregateFooterDropdownSubmenuContent = ({ return ( <> + } > {title} diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader.tsx b/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader.tsx index e4679db7c..760f5e10d 100644 --- a/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader.tsx +++ b/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader.tsx @@ -1,13 +1,6 @@ import styled from '@emotion/styled'; -import { ComponentProps, MouseEvent, ReactElement } from 'react'; -import { Avatar, AvatarProps, IconComponent } from 'twenty-ui'; -import { DropdownMenuHeaderStartIcon } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderStartIcon'; -import { isDefined } from 'twenty-shared'; -import { useTheme } from '@emotion/react'; -import { - Dropdown, - DropdownProps, -} from '@/ui/layout/dropdown/components/Dropdown'; +import { ComponentProps, MouseEvent } from 'react'; +import { IconComponent } from 'twenty-ui'; const StyledHeader = styled.li` align-items: center; @@ -37,7 +30,7 @@ const StyledChildrenWrapper = styled.span` text-overflow: ellipsis; `; -const StyledEndIcon = styled.div` +const StyledEndComponent = styled.div` display: inline-flex; color: ${({ theme }) => theme.font.color.tertiary}; padding: ${({ theme }) => theme.spacing(1)}; @@ -53,50 +46,24 @@ const StyledEndIcon = styled.div` type DropdownMenuHeaderProps = ComponentProps<'li'> & { EndIcon?: IconComponent; onClick?: (event: MouseEvent) => void; - onStartIconClick?: (event: MouseEvent) => void; testId?: string; className?: string; - DropdownOnEndIcon?: ReactElement; -} & ( - | { StartIcon?: IconComponent } - | { StartAvatar?: ReactElement } - ); + StartComponent?: React.ReactNode; + EndComponent?: React.ReactNode; +}; export const DropdownMenuHeader = ({ children, - EndIcon, - onStartIconClick, + StartComponent, onClick, testId, className, - ...props + EndComponent, }: DropdownMenuHeaderProps) => { - const theme = useTheme(); - return ( - {'StartIcon' in props && isDefined(props.StartIcon) && ( - - )} - {!('StartIcon' in props) && - 'StartAvatar' in props && - isDefined(props.StartAvatar) && ( - - )} + {StartComponent && StartComponent} {children} - {'DropdownOnEndIcon' in props && ( - {props.DropdownOnEndIcon} - )} - {!('DropdownOnEndIcon' in props) && EndIcon && ( - - - - )} + {EndComponent && {EndComponent}} ); }; diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderStartIcon.tsx b/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent.tsx similarity index 79% rename from packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderStartIcon.tsx rename to packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent.tsx index bc8274766..b80959b79 100644 --- a/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderStartIcon.tsx +++ b/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent.tsx @@ -25,13 +25,13 @@ const StyledAvatarWrapper = styled.div` padding: ${({ theme }) => theme.spacing(1)}; `; -export const DropdownMenuHeaderStartIcon = ({ +export const DropdownMenuHeaderLeftComponent = ({ onClick, ...props }: { onClick?: (event: MouseEvent) => void } & ( - | { StartIcon: IconComponent } + | { Icon: IconComponent } | { - StartAvatar: ReactElement; + Avatar: ReactElement; } | Record )) => { @@ -39,25 +39,25 @@ export const DropdownMenuHeaderStartIcon = ({ return ( <> - {'StartIcon' in props && + {'Icon' in props && (onClick ? ( ) : ( - ))} - {'StartAvatar' in props && ( - {props.StartAvatar} + {'Avatar' in props && ( + {props.Avatar} )} ); diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderWithDropdownMenu.tsx b/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderWithDropdownMenu.tsx deleted file mode 100644 index d7b530f9b..000000000 --- a/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderWithDropdownMenu.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; -import { IconComponent, IconDotsVertical, LightIconButton } from 'twenty-ui'; -import { SelectHotkeyScope } from '@/ui/input/types/SelectHotkeyScope'; -import { Placement } from '@floating-ui/react'; -import { ReactNode } from 'react'; - -export type DropdownMenuHeaderWithDropdownMenuProps = { - EndIcon?: IconComponent; - dropdownPlacement?: Placement; - dropdownComponents: ReactNode; - dropdownId: string; -}; - -export const DropdownMenuHeaderWithDropdownMenu = ( - props: DropdownMenuHeaderWithDropdownMenuProps, -) => { - return ( -
- - } - dropdownPlacement={props.dropdownPlacement ?? 'bottom-end'} - dropdownComponents={props.dropdownComponents} - dropdownId={props.dropdownId} - dropdownHotkeyScope={{ scope: SelectHotkeyScope.Select }} - /> -
- ); -}; diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/components/__stories__/DropdownMenu.stories.tsx b/packages/twenty-front/src/modules/ui/layout/dropdown/components/__stories__/DropdownMenu.stories.tsx index 28b04e72c..33f63ff49 100644 --- a/packages/twenty-front/src/modules/ui/layout/dropdown/components/__stories__/DropdownMenu.stories.tsx +++ b/packages/twenty-front/src/modules/ui/layout/dropdown/components/__stories__/DropdownMenu.stories.tsx @@ -22,6 +22,7 @@ import { DropdownMenuItemsContainer } from '../DropdownMenuItemsContainer'; import { DropdownMenuSearchInput } from '../DropdownMenuSearchInput'; import { DropdownMenuSeparator } from '../DropdownMenuSeparator'; import { StyledDropdownMenuSubheader } from '../StyledDropdownMenuSubheader'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; const meta: Meta = { title: 'UI/Layout/Dropdown/Dropdown', @@ -219,7 +220,11 @@ export const WithHeaders: Story = { args: { dropdownComponents: ( <> - + + } + > Header Subheader 1 diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/components/__stories__/DropdownMenuHeader.stories.tsx b/packages/twenty-front/src/modules/ui/layout/dropdown/components/__stories__/DropdownMenuHeader.stories.tsx index 57ad19a78..3ed73e189 100644 --- a/packages/twenty-front/src/modules/ui/layout/dropdown/components/__stories__/DropdownMenuHeader.stories.tsx +++ b/packages/twenty-front/src/modules/ui/layout/dropdown/components/__stories__/DropdownMenuHeader.stories.tsx @@ -13,6 +13,7 @@ import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenu import { SelectHotkeyScope } from '@/ui/input/types/SelectHotkeyScope'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; const meta: Meta = { title: 'UI/Layout/Dropdown/DropdownMenuHeader', @@ -31,21 +32,14 @@ export const Text: Story = { }; export const StartIcon: Story = { args: { - StartIcon: IconChevronLeft, + StartComponent: , children: 'Start Icon', }, }; -export const EndIcon: Story = { - args: { - EndIcon: IconChevronRight, - children: 'End Icon', - }, -}; - export const StartAndEndIcon: Story = { args: { - StartIcon: IconChevronLeft, + StartComponent: , EndIcon: IconChevronRight, children: 'Start and End Icon', }, @@ -53,7 +47,7 @@ export const StartAndEndIcon: Story = { export const StartAvatar: Story = { args: { - StartAvatar: ( + StartComponent: ( ), children: 'Avatar', @@ -63,10 +57,10 @@ export const StartAvatar: Story = { export const ContextDropdownAndAvatar: Story = { args: { children: 'Context Dropdown', - StartAvatar: ( + StartComponent: ( ), - DropdownOnEndIcon: ( + EndComponent: ( { dropdownHotkeyScope={{ scope: NavigationDrawerHotKeyScope.MultiWorkspaceDropdownButton, }} - dropdownOffset={{ y: 0, x: 0 }} + dropdownOffset={{ y: -35, x: -5 }} clickableComponent={ { const currentWorkspace = useRecoilValue(currentWorkspaceState); const theme = useTheme(); diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownDefaultComponents.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownDefaultComponents.tsx index 3f2aad279..37c820e67 100644 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownDefaultComponents.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownDefaultComponents.tsx @@ -36,6 +36,7 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { SelectHotkeyScope } from '@/ui/input/types/SelectHotkeyScope'; import { useColorScheme } from '@/ui/theme/hooks/useColorScheme'; import styled from '@emotion/styled'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; const StyledDescription = styled.div` color: ${({ theme }) => theme.font.color.light}; @@ -91,13 +92,17 @@ export const MultiWorkspaceDropdownDefaultComponents = () => { return ( <> + } /> } - DropdownOnEndIcon={ + EndComponent={ { const { t } = useLingui(); @@ -18,8 +19,12 @@ export const MultiWorkspaceDropdownThemesComponents = () => { return ( setMultiWorkspaceDropdownState('default')} + StartComponent={ + setMultiWorkspaceDropdownState('default')} + Icon={IconChevronLeft} + /> + } > {t`Theme`} diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownWorkspacesListComponents.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownWorkspacesListComponents.tsx index 354b2d7ec..4dddb46e7 100644 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownWorkspacesListComponents.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownWorkspacesListComponents.tsx @@ -18,6 +18,7 @@ import { multiWorkspaceDropdownState } from '@/ui/navigation/navigation-drawer/s import { useState } from 'react'; import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput'; import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; export const MultiWorkspaceDropdownWorkspacesListComponents = () => { const currentWorkspace = useRecoilValue(currentWorkspaceState); @@ -37,8 +38,12 @@ export const MultiWorkspaceDropdownWorkspacesListComponents = () => { return ( setMultiWorkspaceDropdownState('default')} + StartComponent={ + setMultiWorkspaceDropdownState('default')} + Icon={IconChevronLeft} + /> + } > {t`Other workspaces`} diff --git a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerContentCreateMode.tsx b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerContentCreateMode.tsx index 1584113fa..d5eafd43b 100644 --- a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerContentCreateMode.tsx +++ b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerContentCreateMode.tsx @@ -34,6 +34,7 @@ import { viewPickerSelectedIconComponentState } from '@/views/view-picker/states import { viewPickerTypeComponentState } from '@/views/view-picker/states/viewPickerTypeComponentState'; import { useMemo, useState } from 'react'; import { useLingui } from '@lingui/react/macro'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; const StyledNoKanbanFieldAvailableContainer = styled.div` color: ${({ theme }) => theme.font.color.light}; @@ -130,7 +131,11 @@ export const ViewPickerContentCreateMode = () => { return ( <> - + + } + > {t`Create view`} diff --git a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerContentEditMode.tsx b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerContentEditMode.tsx index 91e7e349c..db433df1a 100644 --- a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerContentEditMode.tsx +++ b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerContentEditMode.tsx @@ -21,6 +21,7 @@ import { viewPickerInputNameComponentState } from '@/views/view-picker/states/vi import { viewPickerIsDirtyComponentState } from '@/views/view-picker/states/viewPickerIsDirtyComponentState'; import { viewPickerIsPersistingComponentState } from '@/views/view-picker/states/viewPickerIsPersistingComponentState'; import { viewPickerSelectedIconComponentState } from '@/views/view-picker/states/viewPickerSelectedIconComponentState'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; export const ViewPickerContentEditMode = () => { const { setViewPickerMode } = useViewPickerMode(); @@ -68,8 +69,12 @@ export const ViewPickerContentEditMode = () => { return ( <> + } > Edit view diff --git a/packages/twenty-front/src/modules/workflow/workflow-variables/components/WorkflowVariablesDropdownFieldItems.tsx b/packages/twenty-front/src/modules/workflow/workflow-variables/components/WorkflowVariablesDropdownFieldItems.tsx index dc880657b..744c28543 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-variables/components/WorkflowVariablesDropdownFieldItems.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-variables/components/WorkflowVariablesDropdownFieldItems.tsx @@ -26,6 +26,7 @@ import { OverflowingTextWithTooltip, useIcons, } from 'twenty-ui'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; type WorkflowVariablesDropdownFieldItemsProps = { step: StepOutputSchema; @@ -116,8 +117,12 @@ export const WorkflowVariablesDropdownFieldItems = ({ return ( <> + } style={{ position: 'fixed' }} > - + + } + > diff --git a/packages/twenty-front/src/modules/workflow/workflow-variables/components/WorkflowVariablesDropdownWorkflowStepItems.tsx b/packages/twenty-front/src/modules/workflow/workflow-variables/components/WorkflowVariablesDropdownWorkflowStepItems.tsx index 0fd7d8ffc..c95887b42 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-variables/components/WorkflowVariablesDropdownWorkflowStepItems.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-variables/components/WorkflowVariablesDropdownWorkflowStepItems.tsx @@ -12,6 +12,7 @@ import { OverflowingTextWithTooltip, useIcons, } from 'twenty-ui'; +import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; type WorkflowVariablesDropdownWorkflowStepItemsProps = { dropdownId: string; @@ -37,7 +38,14 @@ export const WorkflowVariablesDropdownWorkflowStepItems = ({ return ( <> - + + } + >