From d52cb26599e7e251788266d22b447e08b8fcd9d7 Mon Sep 17 00:00:00 2001 From: Lucas Bordeau Date: Tue, 29 Apr 2025 18:05:12 +0200 Subject: [PATCH] Refactored ObjectFilterDropdown into ViewBarFilterDropdown (#11794) This PR refactors the non-generic part around ObjectFilterDropdown which has been left in statu quo for months. It also removes unused components. Overall this PR is doing renaming and it re-organizes files into their relevant modules. This clarifies a lot what's at the intersection between object-filter-dropdown and views modules. This PR was originally about removing any remaining useEffect around ObjectFilterDropdown but there wasn't any. ## Details ### Removed unused files - GenericEntityFilterChip - SingleEntityObjectFilterDropdownButton (was used for the Task/Note standalone page which doesn't exist anymore) ### Re-organized non-generic components into ViewBarFilterDropdown - Use VIEW_BAR_FILTER_DROPDOWN_ID instead of OBJECT_FILTER_DROPDOWN_ID - Use FILTER_FIELD_LIST_ID for selectable list - Refactored ObjectFilterDropdownButton into a simple ViewBarFilterDropdown - Renamed MultipleFiltersDropdownContent to ViewBarFilterDropdownContent - Renamed MultipleFiltersButton to ViewBarFilterButton - Integrated MultipleFiltersDropdownButton to ViewBarFilterDropdown - Renamed AdvancedFilterButton to ViewBarDetailsAddFilterButton ### Tests Fixed storybook test for ViewBarFilterDrodpown --- .../components/GenericEntityFilterChip.tsx | 21 ------- .../components/ObjectFilterDropdownButton.tsx | 39 ------------ .../ObjectFilterDropdownFieldSelect.tsx | 21 +------ ...jectFilterDropdownFilterSelectMenuItem.tsx | 4 +- ...ctFilterDropdownFilterSelectMenuItemV2.tsx | 5 +- .../ObjectFilterDropdownSubFieldSelect.tsx | 7 ++- ...SingleEntityObjectFilterDropdownButton.tsx | 62 ------------------- ...EntityObjectFilterDropdownButtonEffect.tsx | 39 ------------ .../constants/FilterFieldListId.ts | 1 + .../constants/ObjectFilterDropdownId.ts | 1 - .../src/modules/views/components/ViewBar.tsx | 20 +++--- .../views/components/ViewBarDetails.tsx | 8 +-- .../ViewBarDetailsAddFilterButton.tsx} | 16 ++--- .../components/ViewBarFilterButton.tsx} | 6 +- .../components/ViewBarFilterDropdown.tsx} | 18 +++--- ...BarFilterDropdownAdvancedFilterButton.tsx} | 6 +- .../ViewBarFilterDropdownContent.tsx} | 23 ++++--- .../ViewBarFilterDropdown.stories.tsx} | 57 ++++++++++++++--- .../constants/ViewBarFilterDropdownId.ts | 1 + 19 files changed, 108 insertions(+), 247 deletions(-) delete mode 100644 packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/GenericEntityFilterChip.tsx delete mode 100644 packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownButton.tsx delete mode 100644 packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/SingleEntityObjectFilterDropdownButton.tsx delete mode 100644 packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/SingleEntityObjectFilterDropdownButtonEffect.tsx create mode 100644 packages/twenty-front/src/modules/object-record/object-filter-dropdown/constants/FilterFieldListId.ts delete mode 100644 packages/twenty-front/src/modules/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId.ts rename packages/twenty-front/src/modules/{object-record/object-filter-dropdown/components/AddObjectFilterFromDetailsButton.tsx => views/components/ViewBarDetailsAddFilterButton.tsx} (54%) rename packages/twenty-front/src/modules/{object-record/object-filter-dropdown/components/MultipleFiltersButton.tsx => views/components/ViewBarFilterButton.tsx} (78%) rename packages/twenty-front/src/modules/{object-record/object-filter-dropdown/components/MultipleFiltersDropdownButton.tsx => views/components/ViewBarFilterDropdown.tsx} (73%) rename packages/twenty-front/src/modules/{object-record/object-filter-dropdown/components/AdvancedFilterButton.tsx => views/components/ViewBarFilterDropdownAdvancedFilterButton.tsx} (96%) rename packages/twenty-front/src/modules/{object-record/object-filter-dropdown/components/MultipleFiltersDropdownContent.tsx => views/components/ViewBarFilterDropdownContent.tsx} (69%) rename packages/twenty-front/src/modules/{object-record/object-filter-dropdown/components/__stories__/MultipleFiltersDropdownButton.stories.tsx => views/components/__stories__/ViewBarFilterDropdown.stories.tsx} (74%) create mode 100644 packages/twenty-front/src/modules/views/constants/ViewBarFilterDropdownId.ts diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/GenericEntityFilterChip.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/GenericEntityFilterChip.tsx deleted file mode 100644 index d54eee962..000000000 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/GenericEntityFilterChip.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { RecordFilter } from '../../record-filter/types/RecordFilter'; -import { AvatarChip } from 'twenty-ui/components'; -import { IconComponent } from 'twenty-ui/display'; - -type GenericEntityFilterChipProps = { - filter: RecordFilter; - Icon?: IconComponent; -}; - -export const GenericEntityFilterChip = ({ - filter, - Icon, -}: GenericEntityFilterChipProps) => ( - -); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownButton.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownButton.tsx deleted file mode 100644 index b98d68b53..000000000 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownButton.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope'; - -import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext'; -import { useFilterableFieldMetadataItemsInRecordIndexContext } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItemsInRecordIndexContext'; -import { MultipleFiltersDropdownButton } from './MultipleFiltersDropdownButton'; -import { SingleEntityObjectFilterDropdownButton } from './SingleEntityObjectFilterDropdownButton'; - -type ObjectFilterDropdownButtonProps = { - filterDropdownId: string; - hotkeyScope: HotkeyScope; -}; - -export const ObjectFilterDropdownButton = ({ - filterDropdownId, - hotkeyScope, -}: ObjectFilterDropdownButtonProps) => { - const { filterableFieldMetadataItems } = - useFilterableFieldMetadataItemsInRecordIndexContext(); - - const hasOnlyOneEntityFilter = - filterableFieldMetadataItems.length === 1 && - filterableFieldMetadataItems[0].type === 'RELATION'; - - if (!filterableFieldMetadataItems.length) { - return <>; - } - - return ( - - {hasOnlyOneEntityFilter ? ( - - ) : ( - - )} - - ); -}; diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFieldSelect.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFieldSelect.tsx index 25a302e21..9c1b009f7 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFieldSelect.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFieldSelect.tsx @@ -2,9 +2,7 @@ import styled from '@emotion/styled'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; -import { AdvancedFilterButton } from '@/object-record/object-filter-dropdown/components/AdvancedFilterButton'; import { ObjectFilterDropdownFilterSelectMenuItem } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectMenuItem'; -import { OBJECT_FILTER_DROPDOWN_ID } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId'; import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState'; @@ -14,12 +12,11 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; +import { FILTER_FIELD_LIST_ID } from '@/object-record/object-filter-dropdown/constants/FilterFieldListId'; import { FiltersHotkeyScope } from '@/object-record/object-filter-dropdown/types/FiltersHotkeyScope'; import { useFilterableFieldMetadataItemsInRecordIndexContext } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItemsInRecordIndexContext'; import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2'; -import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly'; import { useLingui } from '@lingui/react/macro'; -import { isDefined } from 'twenty-shared/utils'; export const StyledInput = styled.input` background: transparent; @@ -47,13 +44,7 @@ export const StyledInput = styled.input` } `; -type ObjectFilterDropdownFieldSelectProps = { - isAdvancedFilterButtonVisible?: boolean; -}; - -export const ObjectFilterDropdownFieldSelect = ({ - isAdvancedFilterButtonVisible, -}: ObjectFilterDropdownFieldSelectProps) => { +export const ObjectFilterDropdownFieldSelect = () => { const { recordIndexId } = useRecordIndexContextOrThrow(); const [objectFilterDropdownSearchInput, setObjectFilterDropdownSearchInput] = @@ -95,11 +86,6 @@ export const ObjectFilterDropdownFieldSelect = ({ visibleColumnsFieldMetadataItems.length > 0 && hiddenColumnsFieldMetadataItems.length > 0; - const { currentView } = useGetCurrentViewOnly(); - - const shouldShowAdvancedFilterButton = - isDefined(currentView?.objectMetadataId) && isAdvancedFilterButtonVisible; - const { t } = useLingui(); const selectableFieldMetadataItemIds = [ @@ -124,7 +110,7 @@ export const ObjectFilterDropdownFieldSelect = ({ {visibleColumnsFieldMetadataItems.map((visibleFieldMetadataItem) => ( @@ -142,7 +128,6 @@ export const ObjectFilterDropdownFieldSelect = ({ ))} - {shouldShowAdvancedFilterButton && } ); }; diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectMenuItem.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectMenuItem.tsx index f6eba8512..29218a8b2 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectMenuItem.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectMenuItem.tsx @@ -1,4 +1,3 @@ -import { OBJECT_FILTER_DROPDOWN_ID } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId'; import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState'; import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFilterIsSelectedComponentState'; @@ -8,6 +7,7 @@ import { selectedOperandInDropdownComponentState } from '@/object-record/object- import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; +import { FILTER_FIELD_LIST_ID } from '@/object-record/object-filter-dropdown/constants/FilterFieldListId'; import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState'; import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/utils/isCompositeFieldType'; import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState'; @@ -50,7 +50,7 @@ export const ObjectFilterDropdownFilterSelectMenuItem = ({ objectFilterDropdownFilterIsSelectedComponentState, ); - const { resetSelectedItem } = useSelectableList(OBJECT_FILTER_DROPDOWN_ID); + const { resetSelectedItem } = useSelectableList(FILTER_FIELD_LIST_ID); const isSelectedItem = useRecoilComponentFamilyValueV2( isSelectedItemIdComponentFamilySelector, diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectMenuItemV2.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectMenuItemV2.tsx index 0aa29bb70..b9ee16707 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectMenuItemV2.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectMenuItemV2.tsx @@ -1,6 +1,5 @@ -import { OBJECT_FILTER_DROPDOWN_ID } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId'; - import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; +import { FILTER_FIELD_LIST_ID } from '@/object-record/object-filter-dropdown/constants/FilterFieldListId'; import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/utils/isCompositeFieldType'; import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList'; import { isSelectedItemIdComponentFamilySelector } from '@/ui/layout/selectable-list/states/selectors/isSelectedItemIdComponentFamilySelector'; @@ -17,7 +16,7 @@ export const ObjectFilterDropdownFilterSelectMenuItemV2 = ({ fieldMetadataItemToSelect, onClick, }: ObjectFilterDropdownFilterSelectMenuItemV2Props) => { - const { resetSelectedItem } = useSelectableList(OBJECT_FILTER_DROPDOWN_ID); + const { resetSelectedItem } = useSelectableList(FILTER_FIELD_LIST_ID); const isSelectedItem = useRecoilComponentFamilyValueV2( isSelectedItemIdComponentFamilySelector, diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownSubFieldSelect.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownSubFieldSelect.tsx index f2720a2b9..32c4331eb 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownSubFieldSelect.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownSubFieldSelect.tsx @@ -1,7 +1,7 @@ import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; import { StyledInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownFieldSelect'; -import { OBJECT_FILTER_DROPDOWN_ID } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId'; +import { FILTER_FIELD_LIST_ID } from '@/object-record/object-filter-dropdown/constants/FilterFieldListId'; import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState'; import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector'; import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFilterIsSelectedComponentState'; @@ -138,9 +138,10 @@ export const ObjectFilterDropdownSubFieldSelect = () => { setObjectFilterDropdownFilterIsSelected(false); setSubFieldNameUsedInDropdown(null); }; + const selectedItemId = useRecoilComponentValueV2( selectedItemIdComponentState, - OBJECT_FILTER_DROPDOWN_ID, + FILTER_FIELD_LIST_ID, ); if (!isDefined(objectFilterDropdownSubMenuFieldType)) { @@ -189,7 +190,7 @@ export const ObjectFilterDropdownSubFieldSelect = () => { {compositeFieldTypeFilterableByAnySubField ? ( { - const selectedFilter = useRecoilComponentValueV2( - selectedFilterComponentState, - ); - - const theme = useTheme(); - const { t } = useLingui(); - - return ( - <> - - - {selectedFilter ? ( - - ) : ( - t`Filter` - )} - - - } - dropdownComponents={ - <> - - - - - - } - /> - - ); -}; diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/SingleEntityObjectFilterDropdownButtonEffect.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/SingleEntityObjectFilterDropdownButtonEffect.tsx deleted file mode 100644 index 88c754dd5..000000000 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/SingleEntityObjectFilterDropdownButtonEffect.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; -import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState'; - -import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState'; -import { useFilterableFieldMetadataItemsInRecordIndexContext } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItemsInRecordIndexContext'; -import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands'; -import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2'; -import { useEffect } from 'react'; - -export const SingleEntityObjectFilterDropdownButtonEffect = () => { - const setFieldMetadataItemIdUsedInDropdown = useSetRecoilComponentStateV2( - fieldMetadataItemIdUsedInDropdownComponentState, - ); - - const setSelectedOperandInDropdown = useSetRecoilComponentStateV2( - selectedOperandInDropdownComponentState, - ); - - const { filterableFieldMetadataItems } = - useFilterableFieldMetadataItemsInRecordIndexContext(); - - const firstFieldMetadataItem = filterableFieldMetadataItems[0]; - - useEffect(() => { - setFieldMetadataItemIdUsedInDropdown(firstFieldMetadataItem.id); - - const filterType = getFilterTypeFromFieldType(firstFieldMetadataItem.type); - - const defaultOperand = getRecordFilterOperands({ filterType })[0]; - - setSelectedOperandInDropdown(defaultOperand); - }, [ - firstFieldMetadataItem, - setSelectedOperandInDropdown, - setFieldMetadataItemIdUsedInDropdown, - ]); - - return null; -}; diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/constants/FilterFieldListId.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/constants/FilterFieldListId.ts new file mode 100644 index 000000000..834c68e47 --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/constants/FilterFieldListId.ts @@ -0,0 +1 @@ +export const FILTER_FIELD_LIST_ID = 'filter-field-list'; diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId.ts deleted file mode 100644 index d5c49f970..000000000 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId.ts +++ /dev/null @@ -1 +0,0 @@ -export const OBJECT_FILTER_DROPDOWN_ID = 'filter'; diff --git a/packages/twenty-front/src/modules/views/components/ViewBar.tsx b/packages/twenty-front/src/modules/views/components/ViewBar.tsx index 0f3dcfe0a..35b666c3e 100644 --- a/packages/twenty-front/src/modules/views/components/ViewBar.tsx +++ b/packages/twenty-front/src/modules/views/components/ViewBar.tsx @@ -1,7 +1,6 @@ import { ReactNode } from 'react'; import { useParams } from 'react-router-dom'; -import { ObjectFilterDropdownButton } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownButton'; import { ObjectSortDropdownButton } from '@/object-record/object-sort-dropdown/components/ObjectSortDropdownButton'; import { useIsPrefetchLoading } from '@/prefetch/hooks/useIsPrefetchLoading'; @@ -14,12 +13,15 @@ import { ViewPickerDropdown } from '@/views/view-picker/components/ViewPickerDro import { ViewsHotkeyScope } from '../types/ViewsHotkeyScope'; +import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext'; import { FiltersHotkeyScope } from '@/object-record/object-filter-dropdown/types/FiltersHotkeyScope'; import { VIEW_SORT_DROPDOWN_ID } from '@/object-record/object-sort-dropdown/constants/ViewSortDropdownId'; import { ObjectSortDropdownComponentInstanceContext } from '@/object-record/object-sort-dropdown/states/context/ObjectSortDropdownComponentInstanceContext'; +import { ViewBarFilterDropdown } from '@/views/components/ViewBarFilterDropdown'; import { ViewBarRecordFilterEffect } from '@/views/components/ViewBarRecordFilterEffect'; import { ViewBarRecordFilterGroupEffect } from '@/views/components/ViewBarRecordFilterGroupEffect'; import { ViewBarRecordSortEffect } from '@/views/components/ViewBarRecordSortEffect'; +import { VIEW_BAR_FILTER_DROPDOWN_ID } from '@/views/constants/ViewBarFilterDropdownId'; import { UpdateViewButtonGroup } from './UpdateViewButtonGroup'; import { ViewBarDetails } from './ViewBarDetails'; @@ -61,12 +63,15 @@ export const ViewBar = ({ } rightComponent={ <> - + + + { @@ -244,9 +242,7 @@ export const ViewBarDetails = ({ {hasFilterButton && ( - + )} diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/AddObjectFilterFromDetailsButton.tsx b/packages/twenty-front/src/modules/views/components/ViewBarDetailsAddFilterButton.tsx similarity index 54% rename from packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/AddObjectFilterFromDetailsButton.tsx rename to packages/twenty-front/src/modules/views/components/ViewBarDetailsAddFilterButton.tsx index e21006267..26f87ccc2 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/AddObjectFilterFromDetailsButton.tsx +++ b/packages/twenty-front/src/modules/views/components/ViewBarDetailsAddFilterButton.tsx @@ -1,21 +1,17 @@ -import { OBJECT_FILTER_DROPDOWN_ID } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; +import { VIEW_BAR_FILTER_DROPDOWN_ID } from '@/views/constants/ViewBarFilterDropdownId'; import { useResetFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useResetFilterDropdown'; import { t } from '@lingui/core/macro'; import { IconPlus } from 'twenty-ui/display'; import { LightButton } from 'twenty-ui/input'; -type AddObjectFilterFromDetailsButtonProps = { - filterDropdownId?: string; -}; +export const ViewBarDetailsAddFilterButton = () => { + const { toggleDropdown } = useDropdown(VIEW_BAR_FILTER_DROPDOWN_ID); -export const AddObjectFilterFromDetailsButton = ({ - filterDropdownId, -}: AddObjectFilterFromDetailsButtonProps) => { - const { toggleDropdown } = useDropdown(OBJECT_FILTER_DROPDOWN_ID); - - const { resetFilterDropdown } = useResetFilterDropdown(filterDropdownId); + const { resetFilterDropdown } = useResetFilterDropdown( + VIEW_BAR_FILTER_DROPDOWN_ID, + ); const handleClick = () => { resetFilterDropdown(); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersButton.tsx b/packages/twenty-front/src/modules/views/components/ViewBarFilterButton.tsx similarity index 78% rename from packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersButton.tsx rename to packages/twenty-front/src/modules/views/components/ViewBarFilterButton.tsx index d0b8a9fd6..835ffdac4 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersButton.tsx +++ b/packages/twenty-front/src/modules/views/components/ViewBarFilterButton.tsx @@ -1,14 +1,14 @@ -import { OBJECT_FILTER_DROPDOWN_ID } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId'; import { useResetFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useResetFilterDropdown'; import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; +import { VIEW_BAR_FILTER_DROPDOWN_ID } from '@/views/constants/ViewBarFilterDropdownId'; import { Trans } from '@lingui/react/macro'; -export const MultipleFiltersButton = () => { +export const ViewBarFilterButton = () => { const { resetFilterDropdown } = useResetFilterDropdown(); const { toggleDropdown, isDropdownOpen } = useDropdown( - OBJECT_FILTER_DROPDOWN_ID, + VIEW_BAR_FILTER_DROPDOWN_ID, ); const handleClick = () => { diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersDropdownButton.tsx b/packages/twenty-front/src/modules/views/components/ViewBarFilterDropdown.tsx similarity index 73% rename from packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersDropdownButton.tsx rename to packages/twenty-front/src/modules/views/components/ViewBarFilterDropdown.tsx index 9c694b643..3c13dc749 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersDropdownButton.tsx +++ b/packages/twenty-front/src/modules/views/components/ViewBarFilterDropdown.tsx @@ -1,23 +1,23 @@ -import { OBJECT_FILTER_DROPDOWN_ID } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId'; import { useResetFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useResetFilterDropdown'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope'; +import { VIEW_BAR_FILTER_DROPDOWN_ID } from '@/views/constants/ViewBarFilterDropdownId'; import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState'; import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter'; import { isRecordFilterConsideredEmpty } from '@/object-record/record-filter/utils/isRecordFilterConsideredEmpty'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; +import { ViewBarFilterDropdownContent } from '@/views/components/ViewBarFilterDropdownContent'; import { isDefined } from 'twenty-shared/utils'; -import { MultipleFiltersButton } from './MultipleFiltersButton'; -import { MultipleFiltersDropdownContent } from './MultipleFiltersDropdownContent'; +import { ViewBarFilterButton } from './ViewBarFilterButton'; -type MultipleFiltersDropdownButtonProps = { +type ViewBarFilterDropdownProps = { hotkeyScope: HotkeyScope; }; -export const MultipleFiltersDropdownButton = ({ +export const ViewBarFilterDropdown = ({ hotkeyScope, -}: MultipleFiltersDropdownButtonProps) => { +}: ViewBarFilterDropdownProps) => { const { resetFilterDropdown } = useResetFilterDropdown(); const { removeRecordFilter } = useRemoveRecordFilter(); @@ -42,10 +42,10 @@ export const MultipleFiltersDropdownButton = ({ return ( } - dropdownComponents={} + clickableComponent={} + dropdownComponents={} dropdownHotkeyScope={hotkeyScope} dropdownOffset={{ y: 8 }} onClickOutside={handleDropdownClickOutside} diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/AdvancedFilterButton.tsx b/packages/twenty-front/src/modules/views/components/ViewBarFilterDropdownAdvancedFilterButton.tsx similarity index 96% rename from packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/AdvancedFilterButton.tsx rename to packages/twenty-front/src/modules/views/components/ViewBarFilterDropdownAdvancedFilterButton.tsx index aeb598099..e41b90410 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/AdvancedFilterButton.tsx +++ b/packages/twenty-front/src/modules/views/components/ViewBarFilterDropdownAdvancedFilterButton.tsx @@ -1,9 +1,9 @@ import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById'; import { availableFieldMetadataItemsForFilterFamilySelector } from '@/object-metadata/states/availableFieldMetadataItemsForFilterFamilySelector'; -import { OBJECT_FILTER_DROPDOWN_ID } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId'; import { useUpsertRecordFilterGroup } from '@/object-record/record-filter-group/hooks/useUpsertRecordFilterGroup'; import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState'; import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter'; +import { VIEW_BAR_FILTER_DROPDOWN_ID } from '@/views/constants/ViewBarFilterDropdownId'; import { useSetRecordFilterUsedInAdvancedFilterDropdownRow } from '@/object-record/advanced-filter/hooks/useSetRecordFilterUsedInAdvancedFilterDropdownRow'; import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; @@ -40,7 +40,7 @@ export const StyledPill = styled(Pill)` color: ${({ theme }) => theme.color.blue}; `; -export const AdvancedFilterButton = () => { +export const ViewBarFilterDropdownAdvancedFilterButton = () => { const advancedFilterQuerySubFilterCount = 0; // TODO const { t } = useLingui(); @@ -50,7 +50,7 @@ export const AdvancedFilterButton = () => { ); const { closeDropdown: closeObjectFilterDropdown } = useDropdown( - OBJECT_FILTER_DROPDOWN_ID, + VIEW_BAR_FILTER_DROPDOWN_ID, ); const { currentView } = useGetCurrentViewOnly(); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersDropdownContent.tsx b/packages/twenty-front/src/modules/views/components/ViewBarFilterDropdownContent.tsx similarity index 69% rename from packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersDropdownContent.tsx rename to packages/twenty-front/src/modules/views/components/ViewBarFilterDropdownContent.tsx index 19c88e208..e1e197a12 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersDropdownContent.tsx +++ b/packages/twenty-front/src/modules/views/components/ViewBarFilterDropdownContent.tsx @@ -3,24 +3,20 @@ 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 { ObjectFilterDropdownFieldSelect } from './ObjectFilterDropdownFieldSelect'; +import { ViewBarFilterDropdownAdvancedFilterButton } from '@/views/components/ViewBarFilterDropdownAdvancedFilterButton'; +import { VIEW_BAR_FILTER_DROPDOWN_ID } from '@/views/constants/ViewBarFilterDropdownId'; +import { ObjectFilterDropdownFieldSelect } from '../../object-record/object-filter-dropdown/components/ObjectFilterDropdownFieldSelect'; -type MultipleFiltersDropdownContentProps = { - filterDropdownId?: string; -}; - -export const MultipleFiltersDropdownContent = ({ - filterDropdownId, -}: MultipleFiltersDropdownContentProps) => { +export const ViewBarFilterDropdownContent = () => { const [objectFilterDropdownIsSelectingCompositeField] = useRecoilComponentStateV2( objectFilterDropdownIsSelectingCompositeFieldComponentState, - filterDropdownId, + VIEW_BAR_FILTER_DROPDOWN_ID, ); const [objectFilterDropdownFilterIsSelected] = useRecoilComponentStateV2( objectFilterDropdownFilterIsSelectedComponentState, - filterDropdownId, + VIEW_BAR_FILTER_DROPDOWN_ID, ); const shouldShowCompositeSelectionSubMenu = @@ -32,12 +28,15 @@ export const MultipleFiltersDropdownContent = ({ <> {shouldShowFilterInput ? ( ) : shouldShowCompositeSelectionSubMenu ? ( ) : ( - + <> + + + )} ); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/__stories__/MultipleFiltersDropdownButton.stories.tsx b/packages/twenty-front/src/modules/views/components/__stories__/ViewBarFilterDropdown.stories.tsx similarity index 74% rename from packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/__stories__/MultipleFiltersDropdownButton.stories.tsx rename to packages/twenty-front/src/modules/views/components/__stories__/ViewBarFilterDropdown.stories.tsx index 0354b8b63..a29c2e6ff 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/__stories__/MultipleFiltersDropdownButton.stories.tsx +++ b/packages/twenty-front/src/modules/views/components/__stories__/ViewBarFilterDropdown.stories.tsx @@ -1,20 +1,30 @@ import { Meta, StoryObj } from '@storybook/react'; import { TaskGroups } from '@/activities/tasks/components/TaskGroups'; +import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState'; import { CoreObjectNamePlural } from '@/object-metadata/types/CoreObjectNamePlural'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { formatFieldMetadataItemAsColumnDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsColumnDefinition'; -import { MultipleFiltersDropdownButton } from '@/object-record/object-filter-dropdown/components/MultipleFiltersDropdownButton'; import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext'; import { RecordFilterGroupsComponentInstanceContext } from '@/object-record/record-filter-group/states/context/RecordFilterGroupsComponentInstanceContext'; import { RecordFiltersComponentInstanceContext } from '@/object-record/record-filter/states/context/RecordFiltersComponentInstanceContext'; import { RecordIndexContextProvider } from '@/object-record/record-index/contexts/RecordIndexContext'; import { RecordSortsComponentInstanceContext } from '@/object-record/record-sort/states/context/RecordSortsComponentInstanceContext'; +import { AGGREGATE_OPERATIONS } from '@/object-record/record-table/constants/AggregateOperations'; import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext'; import { tableColumnsComponentState } from '@/object-record/record-table/states/tableColumnsComponentState'; +import { prefetchViewsState } from '@/prefetch/states/prefetchViewsState'; import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2'; +import { ViewBarFilterDropdown } from '@/views/components/ViewBarFilterDropdown'; import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext'; +import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType'; +import { ViewType } from '@/views/types/ViewType'; + +import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId'; +import { VIEW_BAR_FILTER_DROPDOWN_ID } from '@/views/constants/ViewBarFilterDropdownId'; +import { View } from '@/views/types/View'; import { within } from '@storybook/test'; +import { useSetRecoilState } from 'recoil'; import { ComponentDecorator, getCanvasElementForDropdownTesting, @@ -26,22 +36,53 @@ import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadat import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator'; import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems'; -const meta: Meta = { - title: - 'Modules/ObjectRecord/ObjectFilterDropdown/MultipleFiltersDropdownButton', - component: MultipleFiltersDropdownButton, +const meta: Meta = { + title: 'Modules/Views/ViewBarFilterDropdown', + component: ViewBarFilterDropdown, decorators: [ (Story) => { const companyObjectMetadataItem = generatedMockObjectMetadataItems.find( (item) => item.nameSingular === CoreObjectNameSingular.Company, )!; - const instanceId = 'entity-tasks-filter-scope'; + const instanceId = companyObjectMetadataItem.id; const setTableColumns = useSetRecoilComponentStateV2( tableColumnsComponentState, instanceId, ); + const setPrefetchViews = useSetRecoilState(prefetchViewsState); + + const mockView: View = { + id: 'view-1', + name: 'Test View', + objectMetadataId: companyObjectMetadataItem.id, + viewFilters: [], + viewFilterGroups: [], + type: ViewType.Table, + key: null, + isCompact: false, + openRecordIn: ViewOpenRecordInType.SIDE_PANEL, + viewFields: [], + viewGroups: [], + viewSorts: [], + kanbanFieldMetadataId: '', + kanbanAggregateOperation: AGGREGATE_OPERATIONS.count, + icon: '', + kanbanAggregateOperationFieldMetadataId: '', + position: 0, + __typename: 'View', + }; + + setPrefetchViews([mockView]); + + const setCurrentViewId = useSetRecoilComponentStateV2( + contextStoreCurrentViewIdComponentState, + MAIN_CONTEXT_STORE_INSTANCE_ID, + ); + + setCurrentViewId('view-1'); + const columns = companyObjectMetadataItem.fields.map( (fieldMetadataItem, index) => formatFieldMetadataItemAsColumnDefinition({ @@ -74,7 +115,7 @@ const meta: Meta = { value={{ instanceId }} > = { ], args: { hotkeyScope: { - scope: 'object-filter-dropdown', + scope: 'view-bar-filter-dropdown', }, }, }; diff --git a/packages/twenty-front/src/modules/views/constants/ViewBarFilterDropdownId.ts b/packages/twenty-front/src/modules/views/constants/ViewBarFilterDropdownId.ts new file mode 100644 index 000000000..4947c10a3 --- /dev/null +++ b/packages/twenty-front/src/modules/views/constants/ViewBarFilterDropdownId.ts @@ -0,0 +1 @@ +export const VIEW_BAR_FILTER_DROPDOWN_ID = 'view-bar-filter-dropdown';