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 a2cf93c49..d97803fc2 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
@@ -10,7 +10,8 @@ import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
import { ObjectFilterDropdownBooleanSelect } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownBooleanSelect';
-import { ObjectFilterDropdownOperandDropdown } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandDropdown';
+import { ObjectFilterDropdownFilterInputHeader } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterInputHeader';
+import { ObjectFilterDropdownInnerSelectOperandDropdown } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownInnerSelectOperandDropdown';
import { ObjectFilterDropdownTextInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownTextInput';
import { DATE_FILTER_TYPES } from '@/object-record/object-filter-dropdown/constants/DateFilterTypes';
import { DATE_PICKER_DROPDOWN_CONTENT_WIDTH } from '@/object-record/object-filter-dropdown/constants/DatePickerDropdownContentWidth';
@@ -41,7 +42,7 @@ export const ObjectFilterDropdownFilterInput = ({
filterDropdownId,
);
- const isConfigurable =
+ const isOperandWithFilterValue =
selectedOperandInDropdown &&
[
ViewFilterOperand.Is,
@@ -76,25 +77,30 @@ export const ObjectFilterDropdownFilterInput = ({
);
const isDateFilter = DATE_FILTER_TYPES.includes(filterType);
- const isOnlyOperand = !isConfigurable;
+ const isOnlyOperand = !isOperandWithFilterValue;
if (isOnlyOperand) {
return (
-
+
+
);
} else if (isDateFilter) {
return (
-
+
+
+
);
} else {
return (
-
+
+
+
{TEXT_FILTER_TYPES.includes(filterType) && (
)}
diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterInputHeader.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterInputHeader.tsx
new file mode 100644
index 000000000..0d9aa2edd
--- /dev/null
+++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterInputHeader.tsx
@@ -0,0 +1,16 @@
+import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader';
+
+import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
+import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
+
+export const ObjectFilterDropdownFilterInputHeader = () => {
+ const fieldMetadataItemUsedInDropdown = useRecoilComponentValueV2(
+ fieldMetadataItemUsedInDropdownComponentSelector,
+ );
+
+ return (
+
+ {fieldMetadataItemUsedInDropdown?.label}
+
+ );
+};
diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownInnerSelectOperandDropdown.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownInnerSelectOperandDropdown.tsx
new file mode 100644
index 000000000..bb126ae2e
--- /dev/null
+++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownInnerSelectOperandDropdown.tsx
@@ -0,0 +1,69 @@
+import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
+import { useApplyObjectFilterDropdownOperand } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownOperand';
+import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
+import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
+import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState';
+import { getOperandLabel } from '@/object-record/object-filter-dropdown/utils/getOperandLabel';
+import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand';
+import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
+import { DropdownMenuInnerSelect } from '@/ui/layout/dropdown/components/DropdownMenuInnerSelect';
+import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
+import { isDefined } from 'twenty-shared/utils';
+import { SelectOption } from 'twenty-ui/input';
+
+const OBJECT_FILTER_DROPDOWN_INNER_SELECT_OPERAND_DROPDOWN_ID =
+ 'object-filter-dropdown-inner-select-operand-dropdown';
+
+export const ObjectFilterDropdownInnerSelectOperandDropdown = () => {
+ const selectedOperandInDropdown = useRecoilComponentValueV2(
+ selectedOperandInDropdownComponentState,
+ );
+
+ const fieldMetadataItemUsedInDropdown = useRecoilComponentValueV2(
+ fieldMetadataItemUsedInDropdownComponentSelector,
+ );
+
+ const subFieldNameUsedInDropdown = useRecoilComponentValueV2(
+ subFieldNameUsedInDropdownComponentState,
+ );
+
+ const operandsForFilterType = isDefined(fieldMetadataItemUsedInDropdown)
+ ? getRecordFilterOperands({
+ filterType: getFilterTypeFromFieldType(
+ fieldMetadataItemUsedInDropdown.type,
+ ),
+ subFieldName: subFieldNameUsedInDropdown,
+ })
+ : [];
+
+ const options = operandsForFilterType.map((operand) => ({
+ label: getOperandLabel(operand),
+ value: operand,
+ })) as SelectOption[];
+
+ const selectedOption =
+ options.find((option) => option.value === selectedOperandInDropdown) ??
+ options[0];
+
+ const { applyObjectFilterDropdownOperand } =
+ useApplyObjectFilterDropdownOperand();
+
+ const handleOperandChange = (newOperandOption: SelectOption) => {
+ applyObjectFilterDropdownOperand(
+ newOperandOption.value as RecordFilterOperand,
+ );
+ };
+
+ if (!isDefined(selectedOperandInDropdown)) {
+ return null;
+ }
+
+ return (
+
+ );
+};
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 b8d2c7704..27394a2a9 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
@@ -22,6 +22,8 @@ const StyledHeader = styled.li`
background: ${({ theme, onClick }) =>
onClick ? theme.background.transparent.light : 'none'};
}
+
+ flex-shrink: 0;
`;
const StyledChildrenWrapper = styled.span`
diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuInnerSelect.tsx b/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuInnerSelect.tsx
new file mode 100644
index 000000000..37f707a78
--- /dev/null
+++ b/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuInnerSelect.tsx
@@ -0,0 +1,88 @@
+import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
+import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
+import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
+import { DropdownMenuHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownMenuHotkeyScope';
+import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useTheme } from '@emotion/react';
+
+import styled from '@emotion/styled';
+import { IconChevronDown } from 'twenty-ui/display';
+import { SelectOption } from 'twenty-ui/input';
+import { MenuItemSelect } from 'twenty-ui/navigation';
+
+const StyledDropdownMenuInnerSelectDropdownButton = styled.div`
+ align-items: center;
+ color: ${({ theme }) => theme.font.color.secondary};
+ display: flex;
+ font-size: ${({ theme }) => theme.font.size.sm};
+
+ font-weight: ${({ theme }) => theme.font.weight.medium};
+ height: ${({ theme }) => theme.spacing(7)};
+
+ justify-content: space-between;
+
+ padding-left: ${({ theme }) => theme.spacing(2)};
+ padding-right: ${({ theme }) => theme.spacing(2)};
+ width: 100%;
+
+ box-sizing: border-box;
+ cursor: pointer;
+`;
+
+export type DropdownMenuInnerSelectProps = {
+ selectedOption: SelectOption;
+ onChange: (value: SelectOption) => void;
+ options: SelectOption[];
+ dropdownId: string;
+};
+
+export const DropdownMenuInnerSelect = ({
+ selectedOption,
+ onChange,
+ options,
+ dropdownId,
+}: DropdownMenuInnerSelectProps) => {
+ const theme = useTheme();
+
+ const { closeDropdown } = useDropdown(dropdownId);
+
+ return (
+
+ {selectedOption.label}
+
+
+ }
+ dropdownComponents={
+
+
+ {options.map((selectOption) => (
+ {
+ onChange(selectOption);
+ closeDropdown();
+ }}
+ text={selectOption.label}
+ disabled={selectOption.disabled}
+ selected={selectOption.value === selectedOption.value}
+ />
+ ))}
+
+
+ }
+ dropdownHotkeyScope={{
+ scope: DropdownMenuHotkeyScope.InnerSelect,
+ customScopes: {
+ commandMenu: false,
+ commandMenuOpen: false,
+ },
+ }}
+ dropdownId={dropdownId}
+ dropdownOffset={{
+ x: 8,
+ }}
+ />
+ );
+};
diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/constants/DropdownMenuHotkeyScope.ts b/packages/twenty-front/src/modules/ui/layout/dropdown/constants/DropdownMenuHotkeyScope.ts
new file mode 100644
index 000000000..67147f0b1
--- /dev/null
+++ b/packages/twenty-front/src/modules/ui/layout/dropdown/constants/DropdownMenuHotkeyScope.ts
@@ -0,0 +1,3 @@
+export enum DropdownMenuHotkeyScope {
+ InnerSelect = 'dropdown-menu-inner-select',
+}