Removed availableFilterDefinitions as a state but kept its usage as a derived state of objectMetadataItems (#9972)
The global record filter refactor will derive everything at runtime from objectMetadataItemsState, thus removing the need for a filter definition concept. Here we don't yet remove available filter definition usage but we replace the available filter definitions states, we now derive the same value from objectMetadataItemsState. This will allow us to progressively remove the usage of the concept of filter definition, at the end it will then be easy to just remove from the codebase because nothing will use it anymore.
This commit is contained in:
@ -0,0 +1,41 @@
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { getFilterFilterableFieldMetadataItems } from '@/object-metadata/utils/getFilterFilterableFieldMetadataItems';
|
||||
import { checkIfFeatureFlagIsEnabledOnWorkspace } from '@/workspace/utils/checkIfFeatureFlagIsEnabledOnWorkspace';
|
||||
import { selectorFamily } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
||||
|
||||
export const availableFieldMetadataItemsForFilterFamilySelector =
|
||||
selectorFamily({
|
||||
key: 'availableFieldMetadataItemsForFilterFamilySelector',
|
||||
get:
|
||||
({ objectMetadataItemId }: { objectMetadataItemId: string }) =>
|
||||
({ get }) => {
|
||||
const currentWorkspace = get(currentWorkspaceState);
|
||||
const objectMetadataItems = get(objectMetadataItemsState);
|
||||
|
||||
const objectMetadataItem = objectMetadataItems.find(
|
||||
(item) => item.id === objectMetadataItemId,
|
||||
);
|
||||
|
||||
if (!isDefined(objectMetadataItem)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const isJsonFeatureFlagEnabled = checkIfFeatureFlagIsEnabledOnWorkspace(
|
||||
FeatureFlagKey.IsJsonFilterEnabled,
|
||||
currentWorkspace,
|
||||
);
|
||||
|
||||
const filterFilterableFieldMetadataItems =
|
||||
getFilterFilterableFieldMetadataItems({
|
||||
isJsonFilterEnabled: isJsonFeatureFlagEnabled,
|
||||
});
|
||||
|
||||
const availableFieldMetadataItemsForFilter =
|
||||
objectMetadataItem.fields.filter(filterFilterableFieldMetadataItems);
|
||||
|
||||
return availableFieldMetadataItemsForFilter;
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,52 @@
|
||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import {
|
||||
FieldMetadataType,
|
||||
RelationDefinitionType,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
export const getFilterFilterableFieldMetadataItems = ({
|
||||
isJsonFilterEnabled,
|
||||
}: {
|
||||
isJsonFilterEnabled: boolean;
|
||||
}) => {
|
||||
return (field: FieldMetadataItem) => {
|
||||
const isSystemField = field.isSystem;
|
||||
const isFieldActive = field.isActive;
|
||||
|
||||
const isRelationFieldHandled = !(
|
||||
field.type === FieldMetadataType.RELATION &&
|
||||
field.relationDefinition?.direction !==
|
||||
RelationDefinitionType.MANY_TO_ONE &&
|
||||
field.relationDefinition?.direction !== RelationDefinitionType.ONE_TO_ONE
|
||||
);
|
||||
|
||||
const isFieldTypeFilterable = [
|
||||
FieldMetadataType.BOOLEAN,
|
||||
FieldMetadataType.DATE_TIME,
|
||||
FieldMetadataType.DATE,
|
||||
FieldMetadataType.TEXT,
|
||||
FieldMetadataType.EMAILS,
|
||||
FieldMetadataType.NUMBER,
|
||||
FieldMetadataType.LINKS,
|
||||
FieldMetadataType.FULL_NAME,
|
||||
FieldMetadataType.ADDRESS,
|
||||
FieldMetadataType.RELATION,
|
||||
FieldMetadataType.SELECT,
|
||||
FieldMetadataType.MULTI_SELECT,
|
||||
FieldMetadataType.CURRENCY,
|
||||
FieldMetadataType.RATING,
|
||||
FieldMetadataType.ACTOR,
|
||||
FieldMetadataType.PHONES,
|
||||
FieldMetadataType.ARRAY,
|
||||
...(isJsonFilterEnabled ? [FieldMetadataType.RAW_JSON] : []),
|
||||
].includes(field.type);
|
||||
|
||||
const isFieldFilterable =
|
||||
!isSystemField &&
|
||||
isFieldActive &&
|
||||
isRelationFieldHandled &&
|
||||
isFieldTypeFilterable;
|
||||
|
||||
return isFieldFilterable;
|
||||
};
|
||||
};
|
||||
@ -1,17 +1,18 @@
|
||||
import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById';
|
||||
import { availableFieldMetadataItemsForFilterFamilySelector } from '@/object-metadata/states/availableFieldMetadataItemsForFilterFamilySelector';
|
||||
import { formatFieldMetadataItemAsFilterDefinition } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||
import { useUpsertCombinedViewFilterGroup } from '@/object-record/advanced-filter/hooks/useUpsertCombinedViewFilterGroup';
|
||||
import { getRecordFilterOperandsForRecordFilterDefinition } from '@/object-record/record-filter/utils/getRecordFilterOperandsForRecordFilterDefinition';
|
||||
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 { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { ADVANCED_FILTER_DROPDOWN_ID } from '@/views/constants/AdvancedFilterDropdownId';
|
||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
||||
import { useUpsertCombinedViewFilters } from '@/views/hooks/useUpsertCombinedViewFilters';
|
||||
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
|
||||
import { ViewFilterGroup } from '@/views/types/ViewFilterGroup';
|
||||
import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator';
|
||||
import { useCallback } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
import { IconLibraryPlus, IconPlus, LightButton, MenuItem } from 'twenty-ui';
|
||||
import { v4 } from 'uuid';
|
||||
@ -41,7 +42,7 @@ export const AdvancedFilterAddFilterRuleSelect = ({
|
||||
const objectMetadataId =
|
||||
currentViewWithCombinedFiltersAndSorts?.objectMetadataId;
|
||||
|
||||
if (!objectMetadataId) {
|
||||
if (!isDefined(objectMetadataId)) {
|
||||
throw new Error('Object metadata id is missing from current view');
|
||||
}
|
||||
|
||||
@ -49,33 +50,45 @@ export const AdvancedFilterAddFilterRuleSelect = ({
|
||||
objectId: objectMetadataId,
|
||||
});
|
||||
|
||||
const availableFilterDefinitions = useRecoilComponentValueV2(
|
||||
availableFilterDefinitionsComponentState,
|
||||
const availableFieldMetadataItemsForFilter = useRecoilValue(
|
||||
availableFieldMetadataItemsForFilterFamilySelector({
|
||||
objectMetadataItemId: objectMetadataId,
|
||||
}),
|
||||
);
|
||||
|
||||
const getDefaultFilterDefinition = useCallback(() => {
|
||||
const defaultFilterDefinition =
|
||||
availableFilterDefinitions.find(
|
||||
(filterDefinition) =>
|
||||
filterDefinition.fieldMetadataId ===
|
||||
const getDefaultFieldMetadataItem = useCallback(() => {
|
||||
const defaultFieldMetadataItem =
|
||||
availableFieldMetadataItemsForFilter.find(
|
||||
(fieldMetadataItem) =>
|
||||
fieldMetadataItem.id ===
|
||||
objectMetadataItem?.labelIdentifierFieldMetadataId,
|
||||
) ?? availableFilterDefinitions?.[0];
|
||||
) ?? availableFieldMetadataItemsForFilter[0];
|
||||
|
||||
if (!defaultFilterDefinition) {
|
||||
throw new Error('Missing default filter definition');
|
||||
if (!isDefined(defaultFieldMetadataItem)) {
|
||||
throw new Error(
|
||||
`Could not find default field metadata item for object ${objectMetadataId}`,
|
||||
);
|
||||
}
|
||||
|
||||
return defaultFilterDefinition;
|
||||
}, [availableFilterDefinitions, objectMetadataItem]);
|
||||
return defaultFieldMetadataItem;
|
||||
}, [
|
||||
availableFieldMetadataItemsForFilter,
|
||||
objectMetadataItem,
|
||||
objectMetadataId,
|
||||
]);
|
||||
|
||||
const handleAddFilter = () => {
|
||||
closeDropdown();
|
||||
|
||||
const defaultFilterDefinition = getDefaultFilterDefinition();
|
||||
const defaultFieldMetadataItem = getDefaultFieldMetadataItem();
|
||||
|
||||
const defaultFilterDefinition = formatFieldMetadataItemAsFilterDefinition({
|
||||
field: defaultFieldMetadataItem,
|
||||
});
|
||||
|
||||
upsertCombinedViewFilter({
|
||||
id: v4(),
|
||||
fieldMetadataId: defaultFilterDefinition.fieldMetadataId,
|
||||
fieldMetadataId: defaultFieldMetadataItem.id,
|
||||
operand: getRecordFilterOperandsForRecordFilterDefinition(
|
||||
defaultFilterDefinition,
|
||||
)[0],
|
||||
@ -104,11 +117,15 @@ export const AdvancedFilterAddFilterRuleSelect = ({
|
||||
|
||||
upsertCombinedViewFilterGroup(newViewFilterGroup);
|
||||
|
||||
const defaultFilterDefinition = getDefaultFilterDefinition();
|
||||
const defaultFieldMetadataItem = getDefaultFieldMetadataItem();
|
||||
|
||||
const defaultFilterDefinition = formatFieldMetadataItemAsFilterDefinition({
|
||||
field: defaultFieldMetadataItem,
|
||||
});
|
||||
|
||||
upsertCombinedViewFilter({
|
||||
id: v4(),
|
||||
fieldMetadataId: defaultFilterDefinition.fieldMetadataId,
|
||||
fieldMetadataId: defaultFieldMetadataItem.id,
|
||||
operand: getRecordFilterOperandsForRecordFilterDefinition(
|
||||
defaultFilterDefinition,
|
||||
)[0],
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useFilterDefinitionsFromFilterableFieldMetadataItems } from '@/object-record/record-filter/hooks/useFilterDefinitionsFromFilterableFieldMetadataItems';
|
||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
||||
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
|
||||
import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters';
|
||||
|
||||
export const useCurrentViewFilter = ({
|
||||
@ -8,9 +7,8 @@ export const useCurrentViewFilter = ({
|
||||
}: {
|
||||
viewFilterId?: string;
|
||||
}) => {
|
||||
const availableFilterDefinitions = useRecoilComponentValueV2(
|
||||
availableFilterDefinitionsComponentState,
|
||||
);
|
||||
const { filterDefinitions } =
|
||||
useFilterDefinitionsFromFilterableFieldMetadataItems();
|
||||
|
||||
const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView();
|
||||
|
||||
@ -22,10 +20,7 @@ export const useCurrentViewFilter = ({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const [filter] = mapViewFiltersToFilters(
|
||||
[viewFilter],
|
||||
availableFilterDefinitions,
|
||||
);
|
||||
const [filter] = mapViewFiltersToFilters([viewFilter], filterDefinitions);
|
||||
|
||||
return filter;
|
||||
};
|
||||
|
||||
@ -1,15 +1,17 @@
|
||||
import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById';
|
||||
import { availableFieldMetadataItemsForFilterFamilySelector } from '@/object-metadata/states/availableFieldMetadataItemsForFilterFamilySelector';
|
||||
import { formatFieldMetadataItemAsFilterDefinition } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||
import { useUpsertCombinedViewFilterGroup } from '@/object-record/advanced-filter/hooks/useUpsertCombinedViewFilterGroup';
|
||||
import { OBJECT_FILTER_DROPDOWN_ID } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId';
|
||||
import { getRecordFilterOperandsForRecordFilterDefinition } from '@/object-record/record-filter/utils/getRecordFilterOperandsForRecordFilterDefinition';
|
||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { ADVANCED_FILTER_DROPDOWN_ID } from '@/views/constants/AdvancedFilterDropdownId';
|
||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
||||
import { useUpsertCombinedViewFilters } from '@/views/hooks/useUpsertCombinedViewFilters';
|
||||
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
|
||||
import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator';
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
import {
|
||||
IconFilter,
|
||||
MenuItemLeftContent,
|
||||
@ -66,8 +68,10 @@ export const AdvancedFilterButton = () => {
|
||||
objectId: objectMetadataId ?? null,
|
||||
});
|
||||
|
||||
const availableFilterDefinitions = useRecoilComponentValueV2(
|
||||
availableFilterDefinitionsComponentState,
|
||||
const availableFieldMetadataItemsForFilter = useRecoilValue(
|
||||
availableFieldMetadataItemsForFilterFamilySelector({
|
||||
objectMetadataItemId: objectMetadataItem.id,
|
||||
}),
|
||||
);
|
||||
|
||||
const handleClick = () => {
|
||||
@ -88,24 +92,27 @@ export const AdvancedFilterButton = () => {
|
||||
|
||||
upsertCombinedViewFilterGroup(newViewFilterGroup);
|
||||
|
||||
const defaultFilterDefinition =
|
||||
availableFilterDefinitions.find(
|
||||
(filterDefinition) =>
|
||||
filterDefinition.fieldMetadataId ===
|
||||
const defaultFieldMetadataItem =
|
||||
availableFieldMetadataItemsForFilter.find(
|
||||
(fieldMetadataItem) =>
|
||||
fieldMetadataItem.id ===
|
||||
objectMetadataItem?.labelIdentifierFieldMetadataId,
|
||||
) ?? availableFilterDefinitions?.[0];
|
||||
) ?? availableFieldMetadataItemsForFilter[0];
|
||||
|
||||
if (!defaultFilterDefinition) {
|
||||
if (!isDefined(defaultFieldMetadataItem)) {
|
||||
throw new Error('Missing default filter definition');
|
||||
}
|
||||
|
||||
const filterDefinition = formatFieldMetadataItemAsFilterDefinition({
|
||||
field: defaultFieldMetadataItem,
|
||||
});
|
||||
|
||||
upsertCombinedViewFilter({
|
||||
id: v4(),
|
||||
fieldMetadataId: defaultFilterDefinition.fieldMetadataId,
|
||||
operand: getRecordFilterOperandsForRecordFilterDefinition(
|
||||
defaultFilterDefinition,
|
||||
)[0],
|
||||
definition: defaultFilterDefinition,
|
||||
fieldMetadataId: defaultFieldMetadataItem.id,
|
||||
operand:
|
||||
getRecordFilterOperandsForRecordFilterDefinition(filterDefinition)[0],
|
||||
definition: filterDefinition,
|
||||
value: '',
|
||||
displayValue: '',
|
||||
viewFilterGroupId: newViewFilterGroup.id,
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||
|
||||
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
|
||||
import { useFilterableFieldMetadataItems } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItems';
|
||||
import { MultipleFiltersDropdownButton } from './MultipleFiltersDropdownButton';
|
||||
import { SingleEntityObjectFilterDropdownButton } from './SingleEntityObjectFilterDropdownButton';
|
||||
|
||||
@ -15,16 +14,13 @@ export const ObjectFilterDropdownButton = ({
|
||||
filterDropdownId,
|
||||
hotkeyScope,
|
||||
}: ObjectFilterDropdownButtonProps) => {
|
||||
const availableFilterDefinitions = useRecoilComponentValueV2(
|
||||
availableFilterDefinitionsComponentState,
|
||||
filterDropdownId,
|
||||
);
|
||||
const { filterableFieldMetadataItems } = useFilterableFieldMetadataItems();
|
||||
|
||||
const hasOnlyOneEntityFilter =
|
||||
availableFilterDefinitions.length === 1 &&
|
||||
availableFilterDefinitions[0].type === 'RELATION';
|
||||
filterableFieldMetadataItems.length === 1 &&
|
||||
filterableFieldMetadataItems[0].type === 'RELATION';
|
||||
|
||||
if (!availableFilterDefinitions.length) {
|
||||
if (!filterableFieldMetadataItems.length) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
|
||||
@ -19,14 +19,15 @@ import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectab
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
||||
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
|
||||
import { formatFieldMetadataItemAsFilterDefinition } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||
import { advancedFilterViewFilterIdComponentState } from '@/object-record/object-filter-dropdown/states/advancedFilterViewFilterIdComponentState';
|
||||
import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState';
|
||||
import { FiltersHotkeyScope } from '@/object-record/object-filter-dropdown/types/FiltersHotkeyScope';
|
||||
import { useFilterableFieldMetadataItems } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItems';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
|
||||
export const StyledInput = styled.input`
|
||||
@ -80,9 +81,7 @@ export const ObjectFilterDropdownFilterSelect = ({
|
||||
advancedFilterViewFilterId,
|
||||
);
|
||||
|
||||
const availableFilterDefinitions = useRecoilComponentValueV2(
|
||||
availableFilterDefinitionsComponentState,
|
||||
);
|
||||
const { filterableFieldMetadataItems } = useFilterableFieldMetadataItems();
|
||||
|
||||
const visibleTableColumns = useRecoilComponentValueV2(
|
||||
visibleTableColumnsComponentSelector,
|
||||
@ -99,29 +98,29 @@ export const ObjectFilterDropdownFilterSelect = ({
|
||||
(column) => column.fieldMetadataId,
|
||||
);
|
||||
|
||||
const filteredSearchInputFilterDefinitions =
|
||||
availableFilterDefinitions.filter((item) =>
|
||||
item.label
|
||||
const filteredSearchInputFieldMetadataItems =
|
||||
filterableFieldMetadataItems.filter((fieldMetadataItem) =>
|
||||
fieldMetadataItem.label
|
||||
.toLocaleLowerCase()
|
||||
.includes(objectFilterDropdownSearchInput.toLocaleLowerCase()),
|
||||
);
|
||||
|
||||
const visibleColumnsFilterDefinitions = filteredSearchInputFilterDefinitions
|
||||
|
||||
const visibleColumnsFieldMetadataItems = filteredSearchInputFieldMetadataItems
|
||||
.sort((a, b) => {
|
||||
return (
|
||||
visibleColumnsIds.indexOf(a.fieldMetadataId) -
|
||||
visibleColumnsIds.indexOf(b.fieldMetadataId)
|
||||
);
|
||||
return visibleColumnsIds.indexOf(a.id) - visibleColumnsIds.indexOf(b.id);
|
||||
})
|
||||
.filter((item) => visibleColumnsIds.includes(item.fieldMetadataId));
|
||||
.filter((fieldMetadataItem) =>
|
||||
visibleColumnsIds.includes(fieldMetadataItem.id),
|
||||
);
|
||||
|
||||
const hiddenColumnsFilterDefinitions = filteredSearchInputFilterDefinitions
|
||||
const hiddenColumnsFieldMetadataItems = filteredSearchInputFieldMetadataItems
|
||||
.sort((a, b) => a.label.localeCompare(b.label))
|
||||
.filter((item) => hiddenColumnIds.includes(item.fieldMetadataId));
|
||||
.filter((fieldMetadataItem) =>
|
||||
hiddenColumnIds.includes(fieldMetadataItem.id),
|
||||
);
|
||||
|
||||
const selectableListItemIds = availableFilterDefinitions.map(
|
||||
(item) => item.fieldMetadataId,
|
||||
const selectableFieldMetadataItemIds = filterableFieldMetadataItems.map(
|
||||
(fieldMetadataItem) => fieldMetadataItem.id,
|
||||
);
|
||||
|
||||
const { selectFilterDefinitionUsedInDropdown } =
|
||||
@ -134,16 +133,20 @@ export const ObjectFilterDropdownFilterSelect = ({
|
||||
const { resetSelectedItem } = useSelectableList(OBJECT_FILTER_DROPDOWN_ID);
|
||||
|
||||
const handleEnter = (fieldMetadataItemId: string) => {
|
||||
const selectedFilterDefinition = availableFilterDefinitions.find(
|
||||
(item) => item.fieldMetadataId === fieldMetadataItemId,
|
||||
const selectedFieldMetadataItem = filterableFieldMetadataItems.find(
|
||||
(fieldMetadataItem) => fieldMetadataItem.id === fieldMetadataItemId,
|
||||
);
|
||||
|
||||
if (!isDefined(selectedFilterDefinition)) {
|
||||
if (!isDefined(selectedFieldMetadataItem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
resetSelectedItem();
|
||||
|
||||
const selectedFilterDefinition = formatFieldMetadataItemAsFilterDefinition({
|
||||
field: selectedFieldMetadataItem,
|
||||
});
|
||||
|
||||
selectFilterDefinitionUsedInDropdown({
|
||||
filterDefinition: selectedFilterDefinition,
|
||||
});
|
||||
@ -156,8 +159,8 @@ export const ObjectFilterDropdownFilterSelect = ({
|
||||
};
|
||||
|
||||
const shoudShowSeparator =
|
||||
visibleColumnsFilterDefinitions.length > 0 &&
|
||||
hiddenColumnsFilterDefinitions.length > 0;
|
||||
visibleColumnsFieldMetadataItems.length > 0 &&
|
||||
hiddenColumnsFieldMetadataItems.length > 0;
|
||||
|
||||
const { currentViewId, currentViewWithCombinedFiltersAndSorts } =
|
||||
useGetCurrentView();
|
||||
@ -186,32 +189,32 @@ export const ObjectFilterDropdownFilterSelect = ({
|
||||
/>
|
||||
<SelectableList
|
||||
hotkeyScope={FiltersHotkeyScope.ObjectFilterDropdownButton}
|
||||
selectableItemIdArray={selectableListItemIds}
|
||||
selectableItemIdArray={selectableFieldMetadataItemIds}
|
||||
selectableListId={OBJECT_FILTER_DROPDOWN_ID}
|
||||
onEnter={handleEnter}
|
||||
>
|
||||
<DropdownMenuItemsContainer>
|
||||
{visibleColumnsFilterDefinitions.map(
|
||||
(visibleFilterDefinition, index) => (
|
||||
{visibleColumnsFieldMetadataItems.map(
|
||||
(visibleFieldMetadataItem, index) => (
|
||||
<SelectableItem
|
||||
itemId={visibleFilterDefinition.fieldMetadataId}
|
||||
itemId={visibleFieldMetadataItem.id}
|
||||
key={`visible-select-filter-${index}`}
|
||||
>
|
||||
<ObjectFilterDropdownFilterSelectMenuItem
|
||||
filterDefinition={visibleFilterDefinition}
|
||||
fieldMetadataItemToSelect={visibleFieldMetadataItem}
|
||||
/>
|
||||
</SelectableItem>
|
||||
),
|
||||
)}
|
||||
{shoudShowSeparator && <DropdownMenuSeparator />}
|
||||
{hiddenColumnsFilterDefinitions.map(
|
||||
(hiddenFilterDefinition, index) => (
|
||||
{hiddenColumnsFieldMetadataItems.map(
|
||||
(hiddenFieldMetadataItem, index) => (
|
||||
<SelectableItem
|
||||
itemId={hiddenFilterDefinition.fieldMetadataId}
|
||||
itemId={hiddenFieldMetadataItem.id}
|
||||
key={`hidden-select-filter-${index}`}
|
||||
>
|
||||
<ObjectFilterDropdownFilterSelectMenuItem
|
||||
filterDefinition={hiddenFilterDefinition}
|
||||
fieldMetadataItemToSelect={hiddenFieldMetadataItem}
|
||||
/>
|
||||
</SelectableItem>
|
||||
),
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
import { useAdvancedFilterDropdown } from '@/object-record/advanced-filter/hooks/useAdvancedFilterDropdown';
|
||||
import { OBJECT_FILTER_DROPDOWN_ID } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId';
|
||||
|
||||
import { useSelectFilterDefinitionUsedInDropdown } from '@/object-record/object-filter-dropdown/hooks/useSelectFilterDefinitionUsedInDropdown';
|
||||
import { advancedFilterViewFilterIdComponentState } from '@/object-record/object-filter-dropdown/states/advancedFilterViewFilterIdComponentState';
|
||||
import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState';
|
||||
import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFilterIsSelectedComponentState';
|
||||
@ -9,8 +7,12 @@ import { objectFilterDropdownFirstLevelFilterDefinitionComponentState } from '@/
|
||||
import { objectFilterDropdownIsSelectingCompositeFieldComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownIsSelectingCompositeFieldComponentState';
|
||||
import { objectFilterDropdownSubMenuFieldTypeComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSubMenuFieldTypeComponentState';
|
||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||
import { isCompositeField } from '@/object-record/object-filter-dropdown/utils/isCompositeField';
|
||||
import { CompositeFilterableFieldType } from '@/object-record/record-filter/types/CompositeFilterableFieldType';
|
||||
|
||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { formatFieldMetadataItemAsFilterDefinition } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||
import { filterDefinitionUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/filterDefinitionUsedInDropdownComponentState';
|
||||
import { isCompositeField } from '@/object-record/object-filter-dropdown/utils/isCompositeField';
|
||||
import { RecordFilterDefinition } from '@/object-record/record-filter/types/RecordFilterDefinition';
|
||||
import { getRecordFilterOperandsForRecordFilterDefinition } from '@/object-record/record-filter/utils/getRecordFilterOperandsForRecordFilterDefinition';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
||||
@ -23,15 +25,12 @@ import { useRecoilValue } from 'recoil';
|
||||
import { MenuItemSelect, useIcons } from 'twenty-ui';
|
||||
|
||||
export type ObjectFilterDropdownFilterSelectMenuItemProps = {
|
||||
filterDefinition: RecordFilterDefinition;
|
||||
fieldMetadataItemToSelect: FieldMetadataItem;
|
||||
};
|
||||
|
||||
export const ObjectFilterDropdownFilterSelectMenuItem = ({
|
||||
filterDefinition,
|
||||
fieldMetadataItemToSelect,
|
||||
}: ObjectFilterDropdownFilterSelectMenuItemProps) => {
|
||||
const { selectFilterDefinitionUsedInDropdown } =
|
||||
useSelectFilterDefinitionUsedInDropdown();
|
||||
|
||||
const setFieldMetadataItemIdUsedInDropdown = useSetRecoilComponentStateV2(
|
||||
fieldMetadataItemIdUsedInDropdownComponentState,
|
||||
);
|
||||
@ -58,16 +57,24 @@ export const ObjectFilterDropdownFilterSelectMenuItem = ({
|
||||
OBJECT_FILTER_DROPDOWN_ID,
|
||||
);
|
||||
|
||||
const filterDefinitionToSelect = formatFieldMetadataItemAsFilterDefinition({
|
||||
field: fieldMetadataItemToSelect,
|
||||
});
|
||||
|
||||
const isSelectedItem = useRecoilValue(
|
||||
isSelectedItemIdSelector(filterDefinition.fieldMetadataId),
|
||||
isSelectedItemIdSelector(fieldMetadataItemToSelect.id),
|
||||
);
|
||||
|
||||
const isACompositeField = isCompositeField(filterDefinition.type);
|
||||
const isACompositeField = isCompositeField(fieldMetadataItemToSelect.type);
|
||||
|
||||
const setSelectedOperandInDropdown = useSetRecoilComponentStateV2(
|
||||
selectedOperandInDropdownComponentState,
|
||||
);
|
||||
|
||||
const setFilterDefinitionUsedInDropdown = useSetRecoilComponentStateV2(
|
||||
filterDefinitionUsedInDropdownComponentState,
|
||||
);
|
||||
|
||||
const advancedFilterViewFilterId = useRecoilComponentValueV2(
|
||||
advancedFilterViewFilterIdComponentState,
|
||||
);
|
||||
@ -83,13 +90,10 @@ export const ObjectFilterDropdownFilterSelectMenuItem = ({
|
||||
) => {
|
||||
closeAdvancedFilterDropdown();
|
||||
|
||||
selectFilterDefinitionUsedInDropdown({
|
||||
filterDefinition: availableFilterDefinition,
|
||||
});
|
||||
|
||||
setFieldMetadataItemIdUsedInDropdown(
|
||||
availableFilterDefinition.fieldMetadataId,
|
||||
);
|
||||
setFilterDefinitionUsedInDropdown(availableFilterDefinition);
|
||||
|
||||
if (
|
||||
availableFilterDefinition.type === 'RELATION' ||
|
||||
@ -115,12 +119,14 @@ export const ObjectFilterDropdownFilterSelectMenuItem = ({
|
||||
if (isACompositeField) {
|
||||
// TODO: create isCompositeFilterableFieldType type guard
|
||||
setObjectFilterDropdownSubMenuFieldType(
|
||||
filterDefinition.type as CompositeFilterableFieldType,
|
||||
filterDefinitionToSelect.type as CompositeFilterableFieldType,
|
||||
);
|
||||
setObjectFilterDropdownFirstLevelFilterDefinition(
|
||||
filterDefinitionToSelect,
|
||||
);
|
||||
setObjectFilterDropdownFirstLevelFilterDefinition(filterDefinition);
|
||||
setObjectFilterDropdownIsSelectingCompositeField(true);
|
||||
} else {
|
||||
handleSelectFilterDefinition(filterDefinition);
|
||||
handleSelectFilterDefinition(filterDefinitionToSelect);
|
||||
}
|
||||
};
|
||||
|
||||
@ -129,8 +135,8 @@ export const ObjectFilterDropdownFilterSelectMenuItem = ({
|
||||
selected={false}
|
||||
hovered={isSelectedItem}
|
||||
onClick={handleClick}
|
||||
LeftIcon={getIcon(filterDefinition.iconName)}
|
||||
text={filterDefinition.label}
|
||||
LeftIcon={getIcon(filterDefinitionToSelect.iconName)}
|
||||
text={filterDefinitionToSelect.label}
|
||||
hasSubMenu={isACompositeField}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import React from 'react';
|
||||
import { IconChevronDown } from 'twenty-ui';
|
||||
|
||||
import { ObjectFilterDropdownRecordRemoveFilterMenuItem } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordRemoveFilterMenuItem';
|
||||
@ -8,15 +7,10 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM
|
||||
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
|
||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||
|
||||
import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState';
|
||||
import { filterDefinitionUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/filterDefinitionUsedInDropdownComponentState';
|
||||
import { SingleEntityObjectFilterDropdownButtonEffect } from '@/object-record/object-filter-dropdown/components/SingleEntityObjectFilterDropdownButtonEffect';
|
||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { getRecordFilterOperandsForRecordFilterDefinition } from '../../record-filter/utils/getRecordFilterOperandsForRecordFilterDefinition';
|
||||
import { GenericEntityFilterChip } from './GenericEntityFilterChip';
|
||||
import { ObjectFilterDropdownRecordSelect } from './ObjectFilterDropdownRecordSelect';
|
||||
import { ObjectFilterDropdownSearchInput } from './ObjectFilterDropdownSearchInput';
|
||||
@ -32,68 +26,37 @@ export const SingleEntityObjectFilterDropdownButton = ({
|
||||
selectedFilterComponentState,
|
||||
);
|
||||
|
||||
const setFilterDefinitionUsedInDropdown = useSetRecoilComponentStateV2(
|
||||
filterDefinitionUsedInDropdownComponentState,
|
||||
);
|
||||
|
||||
const setFieldMetadataItemIdUsedInDropdown = useSetRecoilComponentStateV2(
|
||||
fieldMetadataItemIdUsedInDropdownComponentState,
|
||||
);
|
||||
|
||||
const setSelectedOperandInDropdown = useSetRecoilComponentStateV2(
|
||||
selectedOperandInDropdownComponentState,
|
||||
);
|
||||
|
||||
const availableFilterDefinitions = useRecoilComponentValueV2(
|
||||
availableFilterDefinitionsComponentState,
|
||||
);
|
||||
|
||||
const availableFilterDefinition = availableFilterDefinitions[0];
|
||||
|
||||
React.useEffect(() => {
|
||||
setFieldMetadataItemIdUsedInDropdown(
|
||||
availableFilterDefinition.fieldMetadataId,
|
||||
);
|
||||
setFilterDefinitionUsedInDropdown(availableFilterDefinition);
|
||||
const defaultOperand = getRecordFilterOperandsForRecordFilterDefinition(
|
||||
availableFilterDefinition,
|
||||
)[0];
|
||||
setSelectedOperandInDropdown(defaultOperand);
|
||||
}, [
|
||||
availableFilterDefinition,
|
||||
setFilterDefinitionUsedInDropdown,
|
||||
setSelectedOperandInDropdown,
|
||||
setFieldMetadataItemIdUsedInDropdown,
|
||||
]);
|
||||
|
||||
const theme = useTheme();
|
||||
const { t } = useLingui();
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
dropdownId={SINGLE_ENTITY_FILTER_DROPDOWN_ID}
|
||||
dropdownHotkeyScope={hotkeyScope}
|
||||
dropdownOffset={{ x: 0, y: -28 }}
|
||||
clickableComponent={
|
||||
<StyledHeaderDropdownButton>
|
||||
{selectedFilter ? (
|
||||
<GenericEntityFilterChip filter={selectedFilter} />
|
||||
) : (
|
||||
t`Filter`
|
||||
)}
|
||||
<IconChevronDown size={theme.icon.size.md} />
|
||||
</StyledHeaderDropdownButton>
|
||||
}
|
||||
dropdownComponents={
|
||||
<>
|
||||
<ObjectFilterDropdownSearchInput />
|
||||
<DropdownMenuSeparator />
|
||||
<ObjectFilterDropdownRecordRemoveFilterMenuItem />
|
||||
<ObjectFilterDropdownRecordSelect
|
||||
viewComponentId={SINGLE_ENTITY_FILTER_DROPDOWN_ID}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<>
|
||||
<SingleEntityObjectFilterDropdownButtonEffect />
|
||||
<Dropdown
|
||||
dropdownId={SINGLE_ENTITY_FILTER_DROPDOWN_ID}
|
||||
dropdownHotkeyScope={hotkeyScope}
|
||||
dropdownOffset={{ x: 0, y: -28 }}
|
||||
clickableComponent={
|
||||
<StyledHeaderDropdownButton>
|
||||
{selectedFilter ? (
|
||||
<GenericEntityFilterChip filter={selectedFilter} />
|
||||
) : (
|
||||
t`Filter`
|
||||
)}
|
||||
<IconChevronDown size={theme.icon.size.md} />
|
||||
</StyledHeaderDropdownButton>
|
||||
}
|
||||
dropdownComponents={
|
||||
<>
|
||||
<ObjectFilterDropdownSearchInput />
|
||||
<DropdownMenuSeparator />
|
||||
<ObjectFilterDropdownRecordRemoveFilterMenuItem />
|
||||
<ObjectFilterDropdownRecordSelect
|
||||
viewComponentId={SINGLE_ENTITY_FILTER_DROPDOWN_ID}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
import { formatFieldMetadataItemAsFilterDefinition } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||
import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState';
|
||||
import { filterDefinitionUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/filterDefinitionUsedInDropdownComponentState';
|
||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||
import { useFilterableFieldMetadataItems } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItems';
|
||||
import { getRecordFilterOperandsForRecordFilterDefinition } from '@/object-record/record-filter/utils/getRecordFilterOperandsForRecordFilterDefinition';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
export const SingleEntityObjectFilterDropdownButtonEffect = () => {
|
||||
const setFilterDefinitionUsedInDropdown = useSetRecoilComponentStateV2(
|
||||
filterDefinitionUsedInDropdownComponentState,
|
||||
);
|
||||
|
||||
const setFieldMetadataItemIdUsedInDropdown = useSetRecoilComponentStateV2(
|
||||
fieldMetadataItemIdUsedInDropdownComponentState,
|
||||
);
|
||||
|
||||
const setSelectedOperandInDropdown = useSetRecoilComponentStateV2(
|
||||
selectedOperandInDropdownComponentState,
|
||||
);
|
||||
|
||||
const { filterableFieldMetadataItems } = useFilterableFieldMetadataItems();
|
||||
|
||||
const firstFieldMetadataItem = filterableFieldMetadataItems[0];
|
||||
|
||||
const firstFieldDefinition = formatFieldMetadataItemAsFilterDefinition({
|
||||
field: firstFieldMetadataItem,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setFieldMetadataItemIdUsedInDropdown(firstFieldDefinition.fieldMetadataId);
|
||||
setFilterDefinitionUsedInDropdown(firstFieldDefinition);
|
||||
|
||||
const defaultOperand =
|
||||
getRecordFilterOperandsForRecordFilterDefinition(firstFieldDefinition)[0];
|
||||
|
||||
setSelectedOperandInDropdown(defaultOperand);
|
||||
}, [
|
||||
firstFieldDefinition,
|
||||
setFilterDefinitionUsedInDropdown,
|
||||
setSelectedOperandInDropdown,
|
||||
setFieldMetadataItemIdUsedInDropdown,
|
||||
]);
|
||||
|
||||
return null;
|
||||
};
|
||||
@ -4,7 +4,6 @@ import { TaskGroups } from '@/activities/tasks/components/TaskGroups';
|
||||
import { CoreObjectNamePlural } from '@/object-metadata/types/CoreObjectNamePlural';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { formatFieldMetadataItemAsColumnDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsColumnDefinition';
|
||||
import { formatFieldMetadataItemAsFilterDefinition } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||
import { MultipleFiltersDropdownButton } from '@/object-record/object-filter-dropdown/components/MultipleFiltersDropdownButton';
|
||||
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
|
||||
import { RecordFiltersComponentInstanceContext } from '@/object-record/record-filter/states/context/RecordFiltersComponentInstanceContext';
|
||||
@ -12,7 +11,6 @@ import { RecordIndexContextProvider } from '@/object-record/record-index/context
|
||||
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
||||
import { tableColumnsComponentState } from '@/object-record/record-table/states/tableColumnsComponentState';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
|
||||
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
||||
import { within } from '@storybook/test';
|
||||
import {
|
||||
@ -35,10 +33,6 @@ const meta: Meta<typeof MultipleFiltersDropdownButton> = {
|
||||
(item) => item.nameSingular === CoreObjectNameSingular.Company,
|
||||
)!;
|
||||
const instanceId = 'entity-tasks-filter-scope';
|
||||
const setAvailableFilterDefinitions = useSetRecoilComponentStateV2(
|
||||
availableFilterDefinitionsComponentState,
|
||||
instanceId,
|
||||
);
|
||||
|
||||
const setTableColumns = useSetRecoilComponentStateV2(
|
||||
tableColumnsComponentState,
|
||||
@ -54,17 +48,8 @@ const meta: Meta<typeof MultipleFiltersDropdownButton> = {
|
||||
}),
|
||||
);
|
||||
|
||||
const filterDefinitions = companyObjectMetadataItem.fields.map(
|
||||
(fieldMetadataItem) =>
|
||||
formatFieldMetadataItemAsFilterDefinition({
|
||||
field: fieldMetadataItem,
|
||||
}),
|
||||
);
|
||||
|
||||
setTableColumns(columns);
|
||||
|
||||
setAvailableFilterDefinitions(filterDefinitions);
|
||||
|
||||
return (
|
||||
<RecordIndexContextProvider
|
||||
value={{
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { advancedFilterViewFilterGroupIdComponentState } from '@/object-record/object-filter-dropdown/states/advancedFilterViewFilterGroupIdComponentState';
|
||||
import { advancedFilterViewFilterIdComponentState } from '@/object-record/object-filter-dropdown/states/advancedFilterViewFilterIdComponentState';
|
||||
import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState';
|
||||
import { filterDefinitionUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/filterDefinitionUsedInDropdownComponentState';
|
||||
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
|
||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||
@ -27,11 +26,6 @@ export const useSelectFilterDefinitionUsedInDropdown = (
|
||||
componentInstanceId,
|
||||
);
|
||||
|
||||
const setFieldMetadataItemIdUsedInDropdown = useSetRecoilComponentStateV2(
|
||||
fieldMetadataItemIdUsedInDropdownComponentState,
|
||||
componentInstanceId,
|
||||
);
|
||||
|
||||
const setSelectedOperandInDropdown = useSetRecoilComponentStateV2(
|
||||
selectedOperandInDropdownComponentState,
|
||||
componentInstanceId,
|
||||
@ -60,7 +54,6 @@ export const useSelectFilterDefinitionUsedInDropdown = (
|
||||
filterDefinition,
|
||||
}: SelectFilterParams) => {
|
||||
setFilterDefinitionUsedInDropdown(filterDefinition);
|
||||
setFieldMetadataItemIdUsedInDropdown(filterDefinition.fieldMetadataId);
|
||||
|
||||
if (
|
||||
filterDefinition.type === 'RELATION' ||
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
|
||||
import { RecordFilterDefinition } from '@/object-record/record-filter/types/RecordFilterDefinition';
|
||||
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||
|
||||
export const availableFilterDefinitionsComponentState = createComponentStateV2<
|
||||
RecordFilterDefinition[]
|
||||
>({
|
||||
key: 'availableFilterDefinitionsComponentState',
|
||||
defaultValue: [],
|
||||
componentInstanceContext: ObjectFilterDropdownComponentInstanceContext,
|
||||
});
|
||||
@ -0,0 +1,23 @@
|
||||
import { availableFieldMetadataItemsForFilterFamilySelector } from '@/object-metadata/states/availableFieldMetadataItemsForFilterFamilySelector';
|
||||
import { formatFieldMetadataItemAsFilterDefinition } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
export const useFilterDefinitionsFromFilterableFieldMetadataItems = () => {
|
||||
const { objectMetadataItem } = useRecordIndexContextOrThrow();
|
||||
|
||||
const availableFieldMetadataItemsForFilter = useRecoilValue(
|
||||
availableFieldMetadataItemsForFilterFamilySelector({
|
||||
objectMetadataItemId: objectMetadataItem.id,
|
||||
}),
|
||||
);
|
||||
|
||||
const filterDefinitions = availableFieldMetadataItemsForFilter.map(
|
||||
(fieldMetadataItem) =>
|
||||
formatFieldMetadataItemAsFilterDefinition({
|
||||
field: fieldMetadataItem,
|
||||
}),
|
||||
);
|
||||
|
||||
return { filterDefinitions };
|
||||
};
|
||||
@ -0,0 +1,15 @@
|
||||
import { availableFieldMetadataItemsForFilterFamilySelector } from '@/object-metadata/states/availableFieldMetadataItemsForFilterFamilySelector';
|
||||
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
export const useFilterableFieldMetadataItems = () => {
|
||||
const { objectMetadataItem } = useRecordIndexContextOrThrow();
|
||||
|
||||
const filterableFieldMetadataItems = useRecoilValue(
|
||||
availableFieldMetadataItemsForFilterFamilySelector({
|
||||
objectMetadataItemId: objectMetadataItem.id,
|
||||
}),
|
||||
);
|
||||
|
||||
return { filterableFieldMetadataItems };
|
||||
};
|
||||
@ -26,6 +26,7 @@ import { RecordIndexActionMenu } from '@/action-menu/components/RecordIndexActio
|
||||
import { ContextStoreCurrentViewTypeEffect } from '@/context-store/components/ContextStoreCurrentViewTypeEffect';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
|
||||
import { useFilterDefinitionsFromFilterableFieldMetadataItems } from '@/object-record/record-filter/hooks/useFilterDefinitionsFromFilterableFieldMetadataItems';
|
||||
import { useSetRecordGroup } from '@/object-record/record-group/hooks/useSetRecordGroup';
|
||||
import { RecordIndexFiltersToContextStoreEffect } from '@/object-record/record-index/components/RecordIndexFiltersToContextStoreEffect';
|
||||
import { RecordIndexTableContainerEffect } from '@/object-record/record-index/components/RecordIndexTableContainerEffect';
|
||||
@ -76,7 +77,7 @@ export const RecordIndexContainer = () => {
|
||||
|
||||
const setRecordGroup = useSetRecordGroup(recordIndexId);
|
||||
|
||||
const { columnDefinitions, filterDefinitions, sortDefinitions } =
|
||||
const { columnDefinitions, sortDefinitions } =
|
||||
useColumnDefinitionsFromFieldMetadata(objectMetadataItem);
|
||||
|
||||
const setRecordIndexViewFilterGroups = useSetRecoilState(
|
||||
@ -179,6 +180,9 @@ export const RecordIndexContainer = () => {
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
);
|
||||
|
||||
const { filterDefinitions } =
|
||||
useFilterDefinitionsFromFilterableFieldMetadataItems();
|
||||
|
||||
const isCommandMenuV2Enabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IsCommandMenuV2Enabled,
|
||||
);
|
||||
|
||||
@ -23,13 +23,12 @@ export const RecordIndexViewBarEffect = ({
|
||||
objectNameSingular,
|
||||
});
|
||||
|
||||
const { columnDefinitions, filterDefinitions, sortDefinitions } =
|
||||
const { columnDefinitions, sortDefinitions } =
|
||||
useColumnDefinitionsFromFieldMetadata(objectMetadataItem);
|
||||
|
||||
const {
|
||||
setViewObjectMetadataId,
|
||||
setAvailableSortDefinitions,
|
||||
setAvailableFilterDefinitions,
|
||||
setAvailableFieldDefinitions,
|
||||
} = useInitViewBar(viewBarId);
|
||||
|
||||
@ -39,15 +38,12 @@ export const RecordIndexViewBarEffect = ({
|
||||
}
|
||||
setViewObjectMetadataId?.(objectMetadataItem.id);
|
||||
setAvailableSortDefinitions?.(sortDefinitions);
|
||||
setAvailableFilterDefinitions?.(filterDefinitions);
|
||||
setAvailableFieldDefinitions?.(columnDefinitions);
|
||||
}, [
|
||||
setViewObjectMetadataId,
|
||||
objectMetadataItem,
|
||||
setAvailableSortDefinitions,
|
||||
sortDefinitions,
|
||||
setAvailableFilterDefinitions,
|
||||
filterDefinitions,
|
||||
setAvailableFieldDefinitions,
|
||||
columnDefinitions,
|
||||
]);
|
||||
|
||||
@ -4,19 +4,19 @@ import { v4 } from 'uuid';
|
||||
import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
|
||||
import { availableFieldMetadataItemsForFilterFamilySelector } from '@/object-metadata/states/availableFieldMetadataItemsForFilterFamilySelector';
|
||||
import { formatFieldMetadataItemAsFilterDefinition } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||
import { useSelectFilterDefinitionUsedInDropdown } from '@/object-record/object-filter-dropdown/hooks/useSelectFilterDefinitionUsedInDropdown';
|
||||
import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState';
|
||||
import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter';
|
||||
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { getRecordFilterOperandsForRecordFilterDefinition } from '@/object-record/record-filter/utils/getRecordFilterOperandsForRecordFilterDefinition';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
||||
import { useUpsertCombinedViewFilters } from '@/views/hooks/useUpsertCombinedViewFilters';
|
||||
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { useRecoilCallback, useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
|
||||
type UseHandleToggleColumnFilterProps = {
|
||||
@ -49,8 +49,10 @@ export const useHandleToggleColumnFilter = ({
|
||||
};
|
||||
}, []);
|
||||
|
||||
const availableFilterDefinitions = useRecoilComponentValueV2(
|
||||
availableFilterDefinitionsComponentState,
|
||||
const availableFieldMetadataItemsForFilter = useRecoilValue(
|
||||
availableFieldMetadataItemsForFilterFamilySelector({
|
||||
objectMetadataItemId: objectMetadataItem.id,
|
||||
}),
|
||||
);
|
||||
|
||||
const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView();
|
||||
@ -80,10 +82,19 @@ export const useHandleToggleColumnFilter = ({
|
||||
);
|
||||
|
||||
if (!existingViewFilter) {
|
||||
const filterDefinition = availableFilterDefinitions.find(
|
||||
(fd) => fd.fieldMetadataId === fieldMetadataId,
|
||||
const fieldMetadataItem = availableFieldMetadataItemsForFilter.find(
|
||||
(fieldMetadataItemToFind) =>
|
||||
fieldMetadataItemToFind.id === fieldMetadataId,
|
||||
);
|
||||
|
||||
if (!isDefined(fieldMetadataItem)) {
|
||||
throw new Error('Field metadata item not found');
|
||||
}
|
||||
|
||||
const filterDefinition = formatFieldMetadataItemAsFilterDefinition({
|
||||
field: fieldMetadataItem,
|
||||
});
|
||||
|
||||
if (!isDefined(filterDefinition)) {
|
||||
throw new Error('Filter definition not found');
|
||||
}
|
||||
@ -118,7 +129,7 @@ export const useHandleToggleColumnFilter = ({
|
||||
upsertCombinedViewFilter,
|
||||
selectFilterDefinitionUsedInDropdown,
|
||||
currentViewWithCombinedFiltersAndSorts,
|
||||
availableFilterDefinitions,
|
||||
availableFieldMetadataItemsForFilter,
|
||||
upsertRecordFilter,
|
||||
setFieldMetadataItemIdUsedInDropdown,
|
||||
],
|
||||
|
||||
@ -5,7 +5,6 @@ import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObje
|
||||
import { useSetRecordIndexEntityCount } from '@/object-record/record-index/hooks/useSetRecordIndexEntityCount';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { SIGN_IN_BACKGROUND_MOCK_COLUMN_DEFINITIONS } from '@/sign-in-background-mock/constants/SignInBackgroundMockColumnDefinitions';
|
||||
import { SIGN_IN_BACKGROUND_MOCK_FILTER_DEFINITIONS } from '@/sign-in-background-mock/constants/SignInBackgroundMockFilterDefinitions';
|
||||
import { SIGN_IN_BACKGROUND_MOCK_SORT_DEFINITIONS } from '@/sign-in-background-mock/constants/SignInBackgroundMockSortDefinitions';
|
||||
import { SIGN_IN_BACKGROUND_MOCK_VIEW_FIELDS } from '@/sign-in-background-mock/constants/SignInBackgroundMockViewFields';
|
||||
import { useInitViewBar } from '@/views/hooks/useInitViewBar';
|
||||
@ -37,7 +36,6 @@ export const SignInBackgroundMockContainerEffect = ({
|
||||
|
||||
const {
|
||||
setAvailableSortDefinitions,
|
||||
setAvailableFilterDefinitions,
|
||||
setAvailableFieldDefinitions,
|
||||
setViewObjectMetadataId,
|
||||
} = useInitViewBar(viewId);
|
||||
@ -48,7 +46,6 @@ export const SignInBackgroundMockContainerEffect = ({
|
||||
setViewObjectMetadataId?.(objectMetadataItem.id);
|
||||
|
||||
setAvailableSortDefinitions?.(SIGN_IN_BACKGROUND_MOCK_SORT_DEFINITIONS);
|
||||
setAvailableFilterDefinitions?.(SIGN_IN_BACKGROUND_MOCK_FILTER_DEFINITIONS);
|
||||
setAvailableFieldDefinitions?.(SIGN_IN_BACKGROUND_MOCK_COLUMN_DEFINITIONS);
|
||||
|
||||
setAvailableTableColumns(SIGN_IN_BACKGROUND_MOCK_COLUMN_DEFINITIONS);
|
||||
@ -62,7 +59,6 @@ export const SignInBackgroundMockContainerEffect = ({
|
||||
}, [
|
||||
setViewObjectMetadataId,
|
||||
setAvailableSortDefinitions,
|
||||
setAvailableFilterDefinitions,
|
||||
setAvailableFieldDefinitions,
|
||||
objectMetadataItem,
|
||||
setAvailableTableColumns,
|
||||
|
||||
@ -1,23 +1,16 @@
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { EditableFilterChip } from '@/views/components/EditableFilterChip';
|
||||
|
||||
import { ObjectFilterOperandSelectAndInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterOperandSelectAndInput';
|
||||
import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState';
|
||||
import { filterDefinitionUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/filterDefinitionUsedInDropdownComponentState';
|
||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||
import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter';
|
||||
import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { EditableFilterDropdownButtonEffect } from '@/views/components/EditableFilterDropdownButtonEffect';
|
||||
import { useDeleteCombinedViewFilters } from '@/views/hooks/useDeleteCombinedViewFilters';
|
||||
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
|
||||
type EditableFilterDropdownButtonProps = {
|
||||
viewFilterDropdownId: string;
|
||||
@ -30,57 +23,10 @@ export const EditableFilterDropdownButton = ({
|
||||
viewFilter,
|
||||
hotkeyScope,
|
||||
}: EditableFilterDropdownButtonProps) => {
|
||||
const setFilterDefinitionUsedInDropdown = useSetRecoilComponentStateV2(
|
||||
filterDefinitionUsedInDropdownComponentState,
|
||||
viewFilterDropdownId,
|
||||
);
|
||||
|
||||
const setFieldMetadataItemIdUsedInDropdown = useSetRecoilComponentStateV2(
|
||||
fieldMetadataItemIdUsedInDropdownComponentState,
|
||||
);
|
||||
|
||||
const setSelectedOperandInDropdown = useSetRecoilComponentStateV2(
|
||||
selectedOperandInDropdownComponentState,
|
||||
viewFilterDropdownId,
|
||||
);
|
||||
|
||||
const setSelectedFilter = useSetRecoilComponentStateV2(
|
||||
selectedFilterComponentState,
|
||||
viewFilterDropdownId,
|
||||
);
|
||||
|
||||
// TODO: verify this instance id works
|
||||
const availableFilterDefinitions = useRecoilComponentValueV2(
|
||||
availableFilterDefinitionsComponentState,
|
||||
viewFilterDropdownId,
|
||||
);
|
||||
|
||||
const { closeDropdown } = useDropdown(viewFilterDropdownId);
|
||||
|
||||
const { deleteCombinedViewFilter } = useDeleteCombinedViewFilters();
|
||||
|
||||
useEffect(() => {
|
||||
const filterDefinition = availableFilterDefinitions.find(
|
||||
(filterDefinition) =>
|
||||
filterDefinition.fieldMetadataId === viewFilter.fieldMetadataId,
|
||||
);
|
||||
|
||||
if (isDefined(filterDefinition)) {
|
||||
setFilterDefinitionUsedInDropdown(filterDefinition);
|
||||
setFieldMetadataItemIdUsedInDropdown(filterDefinition.fieldMetadataId);
|
||||
setSelectedOperandInDropdown(viewFilter.operand);
|
||||
setSelectedFilter(viewFilter);
|
||||
}
|
||||
}, [
|
||||
availableFilterDefinitions,
|
||||
setFilterDefinitionUsedInDropdown,
|
||||
setFieldMetadataItemIdUsedInDropdown,
|
||||
viewFilter,
|
||||
setSelectedOperandInDropdown,
|
||||
setSelectedFilter,
|
||||
viewFilterDropdownId,
|
||||
]);
|
||||
|
||||
const { removeRecordFilter } = useRemoveRecordFilter();
|
||||
|
||||
const handleRemove = () => {
|
||||
@ -108,20 +54,26 @@ export const EditableFilterDropdownButton = ({
|
||||
}, [viewFilter, deleteCombinedViewFilter, removeRecordFilter]);
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
dropdownId={viewFilterDropdownId}
|
||||
clickableComponent={
|
||||
<EditableFilterChip viewFilter={viewFilter} onRemove={handleRemove} />
|
||||
}
|
||||
dropdownComponents={
|
||||
<ObjectFilterOperandSelectAndInput
|
||||
filterDropdownId={viewFilterDropdownId}
|
||||
/>
|
||||
}
|
||||
dropdownHotkeyScope={hotkeyScope}
|
||||
dropdownOffset={{ y: 8, x: 0 }}
|
||||
dropdownPlacement="bottom-start"
|
||||
onClickOutside={handleDropdownClickOutside}
|
||||
/>
|
||||
<>
|
||||
<EditableFilterDropdownButtonEffect
|
||||
viewFilterDropdownId={viewFilterDropdownId}
|
||||
viewFilter={viewFilter}
|
||||
/>
|
||||
<Dropdown
|
||||
dropdownId={viewFilterDropdownId}
|
||||
clickableComponent={
|
||||
<EditableFilterChip viewFilter={viewFilter} onRemove={handleRemove} />
|
||||
}
|
||||
dropdownComponents={
|
||||
<ObjectFilterOperandSelectAndInput
|
||||
filterDropdownId={viewFilterDropdownId}
|
||||
/>
|
||||
}
|
||||
dropdownHotkeyScope={hotkeyScope}
|
||||
dropdownOffset={{ y: 8, x: 0 }}
|
||||
dropdownPlacement="bottom-start"
|
||||
onClickOutside={handleDropdownClickOutside}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@ -0,0 +1,74 @@
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { formatFieldMetadataItemAsFilterDefinition } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||
import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState';
|
||||
import { filterDefinitionUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/filterDefinitionUsedInDropdownComponentState';
|
||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||
import { useFilterableFieldMetadataItems } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItems';
|
||||
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
|
||||
type EditableFilterDropdownButtonEffectProps = {
|
||||
viewFilterDropdownId: string;
|
||||
viewFilter: RecordFilter;
|
||||
};
|
||||
|
||||
export const EditableFilterDropdownButtonEffect = ({
|
||||
viewFilterDropdownId,
|
||||
viewFilter,
|
||||
}: EditableFilterDropdownButtonEffectProps) => {
|
||||
const setFilterDefinitionUsedInDropdown = useSetRecoilComponentStateV2(
|
||||
filterDefinitionUsedInDropdownComponentState,
|
||||
viewFilterDropdownId,
|
||||
);
|
||||
|
||||
const setFieldMetadataItemIdUsedInDropdown = useSetRecoilComponentStateV2(
|
||||
fieldMetadataItemIdUsedInDropdownComponentState,
|
||||
);
|
||||
|
||||
const setSelectedOperandInDropdown = useSetRecoilComponentStateV2(
|
||||
selectedOperandInDropdownComponentState,
|
||||
viewFilterDropdownId,
|
||||
);
|
||||
|
||||
const setSelectedFilter = useSetRecoilComponentStateV2(
|
||||
selectedFilterComponentState,
|
||||
viewFilterDropdownId,
|
||||
);
|
||||
|
||||
const { filterableFieldMetadataItems } = useFilterableFieldMetadataItems();
|
||||
|
||||
useEffect(() => {
|
||||
const fieldMetadataItem = filterableFieldMetadataItems.find(
|
||||
(fieldMetadataItem) =>
|
||||
fieldMetadataItem.id === viewFilter.fieldMetadataId,
|
||||
);
|
||||
|
||||
if (!isDefined(fieldMetadataItem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const filterDefinition = formatFieldMetadataItemAsFilterDefinition({
|
||||
field: fieldMetadataItem,
|
||||
});
|
||||
|
||||
if (isDefined(filterDefinition)) {
|
||||
setFilterDefinitionUsedInDropdown(filterDefinition);
|
||||
setFieldMetadataItemIdUsedInDropdown(filterDefinition.fieldMetadataId);
|
||||
setSelectedOperandInDropdown(viewFilter.operand);
|
||||
setSelectedFilter(viewFilter);
|
||||
}
|
||||
}, [
|
||||
filterableFieldMetadataItems,
|
||||
setFilterDefinitionUsedInDropdown,
|
||||
setFieldMetadataItemIdUsedInDropdown,
|
||||
viewFilter,
|
||||
setSelectedOperandInDropdown,
|
||||
setSelectedFilter,
|
||||
viewFilterDropdownId,
|
||||
]);
|
||||
|
||||
return null;
|
||||
};
|
||||
@ -4,7 +4,6 @@ import { useContext, useEffect, useState } from 'react';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { ViewEventContext } from '@/views/events/contexts/ViewEventContext';
|
||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
||||
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
|
||||
import { isPersistingViewFieldsComponentState } from '@/views/states/isPersistingViewFieldsComponentState';
|
||||
import { View } from '@/views/types/View';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
@ -23,11 +22,6 @@ export const ViewBarEffect = ({ viewBarId }: ViewBarEffectProps) => {
|
||||
View | undefined
|
||||
>(undefined);
|
||||
|
||||
const availableFilterDefinitions = useRecoilComponentValueV2(
|
||||
availableFilterDefinitionsComponentState,
|
||||
viewBarId,
|
||||
);
|
||||
|
||||
const isPersistingViewFields = useRecoilComponentValueV2(
|
||||
isPersistingViewFieldsComponentState,
|
||||
viewBarId,
|
||||
@ -52,7 +46,6 @@ export const ViewBarEffect = ({ viewBarId }: ViewBarEffectProps) => {
|
||||
}
|
||||
}
|
||||
}, [
|
||||
availableFilterDefinitions,
|
||||
currentViewSnapshot,
|
||||
currentViewWithCombinedFiltersAndSorts,
|
||||
isPersistingViewFields,
|
||||
|
||||
@ -8,7 +8,6 @@ import { filterDefinitionUsedInDropdownComponentState } from '@/object-record/ob
|
||||
import { objectFilterDropdownSelectedOptionValuesComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedOptionValuesComponentState';
|
||||
import { objectFilterDropdownSelectedRecordIdsComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsComponentState';
|
||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
||||
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
|
||||
import { jsonRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/jsonRelationFilterValueSchema';
|
||||
import { simpleRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/simpleRelationFilterValueSchema';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
@ -22,10 +21,6 @@ export const ViewBarFilterEffect = ({
|
||||
}: ViewBarFilterEffectProps) => {
|
||||
const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView();
|
||||
|
||||
const availableFilterDefinitions = useRecoilComponentValueV2(
|
||||
availableFilterDefinitionsComponentState,
|
||||
);
|
||||
|
||||
const filterDefinitionUsedInDropdown = useRecoilComponentValueV2(
|
||||
filterDefinitionUsedInDropdownComponentState,
|
||||
filterDropdownId,
|
||||
@ -42,18 +37,6 @@ export const ViewBarFilterEffect = ({
|
||||
filterDropdownId,
|
||||
);
|
||||
|
||||
// TODO: verify this instance id works
|
||||
const setAvailableFilterDefinitions = useSetRecoilComponentStateV2(
|
||||
availableFilterDefinitionsComponentState,
|
||||
filterDropdownId,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (isDefined(availableFilterDefinitions)) {
|
||||
setAvailableFilterDefinitions(availableFilterDefinitions);
|
||||
}
|
||||
}, [availableFilterDefinitions, setAvailableFilterDefinitions]);
|
||||
|
||||
useEffect(() => {
|
||||
if (filterDefinitionUsedInDropdown?.type === 'RELATION') {
|
||||
const viewFilterUsedInDropdown =
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import { formatFieldMetadataItemAsFilterDefinition } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||
import { useFilterableFieldMetadataItems } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItems';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData';
|
||||
import { PrefetchKey } from '@/prefetch/types/PrefetchKey';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
|
||||
import { currentViewIdComponentState } from '@/views/states/currentViewIdComponentState';
|
||||
import { View } from '@/views/types/View';
|
||||
import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters';
|
||||
@ -21,29 +22,31 @@ export const ViewBarRecordFilterEffect = () => {
|
||||
currentRecordFiltersComponentState,
|
||||
);
|
||||
|
||||
const availableFilterDefinitions = useRecoilComponentValueV2(
|
||||
availableFilterDefinitionsComponentState,
|
||||
);
|
||||
const { filterableFieldMetadataItems } = useFilterableFieldMetadataItems();
|
||||
|
||||
useEffect(() => {
|
||||
if (isDataPrefetched) {
|
||||
const currentView = views.find((view) => view.id === currentViewId);
|
||||
|
||||
const filterDefinitions = filterableFieldMetadataItems.map(
|
||||
(fieldMetadataItem) =>
|
||||
formatFieldMetadataItemAsFilterDefinition({
|
||||
field: fieldMetadataItem,
|
||||
}),
|
||||
);
|
||||
|
||||
if (isDefined(currentView)) {
|
||||
setCurrentRecordFilters(
|
||||
mapViewFiltersToFilters(
|
||||
currentView.viewFilters,
|
||||
availableFilterDefinitions,
|
||||
),
|
||||
mapViewFiltersToFilters(currentView.viewFilters, filterDefinitions),
|
||||
);
|
||||
}
|
||||
}
|
||||
}, [
|
||||
isDataPrefetched,
|
||||
views,
|
||||
availableFilterDefinitions,
|
||||
currentViewId,
|
||||
setCurrentRecordFilters,
|
||||
filterableFieldMetadataItems,
|
||||
]);
|
||||
|
||||
return null;
|
||||
|
||||
@ -1,30 +1,42 @@
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
|
||||
import { formatFieldMetadataItemAsFilterDefinition } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { RecordFilterDefinition } from '@/object-record/record-filter/types/RecordFilterDefinition';
|
||||
import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
|
||||
import { currentViewIdComponentState } from '@/views/states/currentViewIdComponentState';
|
||||
import { ViewFilter } from '@/views/types/ViewFilter';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper';
|
||||
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
||||
import { useApplyCurrentViewFiltersToCurrentRecordFilters } from '../useApplyCurrentViewFiltersToCurrentRecordFilters';
|
||||
|
||||
jest.mock('@/prefetch/hooks/usePrefetchedData');
|
||||
|
||||
describe('useApplyCurrentViewFiltersToCurrentRecordFilters', () => {
|
||||
const mockFilterDefinition: RecordFilterDefinition = {
|
||||
fieldMetadataId: 'field-1',
|
||||
label: 'Test Field',
|
||||
type: 'TEXT',
|
||||
iconName: 'IconText',
|
||||
};
|
||||
const mockObjectMetadataItem = generatedMockObjectMetadataItems.find(
|
||||
(item) => item.nameSingular === 'company',
|
||||
);
|
||||
|
||||
if (!isDefined(mockObjectMetadataItem)) {
|
||||
throw new Error(
|
||||
'Missing mock object metadata item with name singular "company"',
|
||||
);
|
||||
}
|
||||
|
||||
const mockFieldMetadataItem = mockObjectMetadataItem.fields[0];
|
||||
|
||||
const mockFilterDefinition: RecordFilterDefinition =
|
||||
formatFieldMetadataItemAsFilterDefinition({
|
||||
field: mockFieldMetadataItem,
|
||||
});
|
||||
|
||||
const mockViewFilter: ViewFilter = {
|
||||
__typename: 'ViewFilter',
|
||||
id: 'filter-1',
|
||||
fieldMetadataId: 'field-1',
|
||||
fieldMetadataId: mockFieldMetadataItem.id,
|
||||
operand: ViewFilterOperand.Contains,
|
||||
value: 'test',
|
||||
displayValue: 'test',
|
||||
@ -36,17 +48,15 @@ describe('useApplyCurrentViewFiltersToCurrentRecordFilters', () => {
|
||||
const mockView = {
|
||||
id: 'view-1',
|
||||
name: 'Test View',
|
||||
objectMetadataId: 'object-1',
|
||||
objectMetadataId: mockObjectMetadataItem.id,
|
||||
viewFilters: [mockViewFilter],
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
it('should apply filters from current view', () => {
|
||||
(usePrefetchedData as jest.Mock).mockReturnValue({
|
||||
records: [mockView],
|
||||
});
|
||||
});
|
||||
|
||||
it('should apply filters from current view', () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const { applyCurrentViewFiltersToCurrentRecordFilters } =
|
||||
@ -70,12 +80,6 @@ describe('useApplyCurrentViewFiltersToCurrentRecordFilters', () => {
|
||||
}),
|
||||
mockView.id,
|
||||
);
|
||||
snapshot.set(
|
||||
availableFilterDefinitionsComponentState.atomFamily({
|
||||
instanceId: 'instanceId',
|
||||
}),
|
||||
[mockFilterDefinition],
|
||||
);
|
||||
},
|
||||
}),
|
||||
},
|
||||
@ -127,12 +131,6 @@ describe('useApplyCurrentViewFiltersToCurrentRecordFilters', () => {
|
||||
}),
|
||||
mockView.id,
|
||||
);
|
||||
snapshot.set(
|
||||
availableFilterDefinitionsComponentState.atomFamily({
|
||||
instanceId: 'instanceId',
|
||||
}),
|
||||
[mockFilterDefinition],
|
||||
);
|
||||
},
|
||||
}),
|
||||
},
|
||||
@ -178,12 +176,6 @@ describe('useApplyCurrentViewFiltersToCurrentRecordFilters', () => {
|
||||
}),
|
||||
mockView.id,
|
||||
);
|
||||
snapshot.set(
|
||||
availableFilterDefinitionsComponentState.atomFamily({
|
||||
instanceId: 'instanceId',
|
||||
}),
|
||||
[mockFilterDefinition],
|
||||
);
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
||||
@ -1,26 +1,38 @@
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
|
||||
import { formatFieldMetadataItemAsFilterDefinition } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { RecordFilterDefinition } from '@/object-record/record-filter/types/RecordFilterDefinition';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
|
||||
import { ViewFilter } from '@/views/types/ViewFilter';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper';
|
||||
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
||||
import { useApplyViewFiltersToCurrentRecordFilters } from '../useApplyViewFiltersToCurrentRecordFilters';
|
||||
|
||||
describe('useApplyViewFiltersToCurrentRecordFilters', () => {
|
||||
const mockAvailableFilterDefinition: RecordFilterDefinition = {
|
||||
fieldMetadataId: 'field-1',
|
||||
label: 'Test Field',
|
||||
type: 'TEXT',
|
||||
iconName: 'IconText',
|
||||
};
|
||||
const mockObjectMetadataItem = generatedMockObjectMetadataItems.find(
|
||||
(item) => item.nameSingular === 'company',
|
||||
);
|
||||
|
||||
if (!isDefined(mockObjectMetadataItem)) {
|
||||
throw new Error(
|
||||
'Missing mock object metadata item with name singular "company"',
|
||||
);
|
||||
}
|
||||
|
||||
const mockFieldMetadataItem = mockObjectMetadataItem.fields[0];
|
||||
|
||||
const mockAvailableFilterDefinition: RecordFilterDefinition =
|
||||
formatFieldMetadataItemAsFilterDefinition({
|
||||
field: mockFieldMetadataItem,
|
||||
});
|
||||
|
||||
const mockViewFilter: ViewFilter = {
|
||||
__typename: 'ViewFilter',
|
||||
id: 'filter-1',
|
||||
fieldMetadataId: 'field-1',
|
||||
fieldMetadataId: mockFieldMetadataItem.id,
|
||||
operand: ViewFilterOperand.Contains,
|
||||
value: 'test',
|
||||
displayValue: 'test',
|
||||
@ -42,16 +54,7 @@ describe('useApplyViewFiltersToCurrentRecordFilters', () => {
|
||||
return { applyViewFiltersToCurrentRecordFilters, currentFilters };
|
||||
},
|
||||
{
|
||||
wrapper: getJestMetadataAndApolloMocksWrapper({
|
||||
onInitializeRecoilSnapshot: (snapshot) => {
|
||||
snapshot.set(
|
||||
availableFilterDefinitionsComponentState.atomFamily({
|
||||
instanceId: 'instanceId',
|
||||
}),
|
||||
[mockAvailableFilterDefinition],
|
||||
);
|
||||
},
|
||||
}),
|
||||
wrapper: getJestMetadataAndApolloMocksWrapper({}),
|
||||
},
|
||||
);
|
||||
|
||||
@ -86,16 +89,7 @@ describe('useApplyViewFiltersToCurrentRecordFilters', () => {
|
||||
return { applyViewFiltersToCurrentRecordFilters, currentFilters };
|
||||
},
|
||||
{
|
||||
wrapper: getJestMetadataAndApolloMocksWrapper({
|
||||
onInitializeRecoilSnapshot: (snapshot) => {
|
||||
snapshot.set(
|
||||
availableFilterDefinitionsComponentState.atomFamily({
|
||||
instanceId: 'instanceId',
|
||||
}),
|
||||
[mockAvailableFilterDefinition],
|
||||
);
|
||||
},
|
||||
}),
|
||||
wrapper: getJestMetadataAndApolloMocksWrapper({}),
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { useFilterDefinitionsFromFilterableFieldMetadataItems } from '@/object-record/record-filter/hooks/useFilterDefinitionsFromFilterableFieldMetadataItems';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData';
|
||||
import { PrefetchKey } from '@/prefetch/types/PrefetchKey';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
|
||||
import { currentViewIdComponentState } from '@/views/states/currentViewIdComponentState';
|
||||
import { View } from '@/views/types/View';
|
||||
import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters';
|
||||
@ -19,19 +19,15 @@ export const useApplyCurrentViewFiltersToCurrentRecordFilters = () => {
|
||||
currentRecordFiltersComponentState,
|
||||
);
|
||||
|
||||
const availableFilterDefinitions = useRecoilComponentValueV2(
|
||||
availableFilterDefinitionsComponentState,
|
||||
);
|
||||
const { filterDefinitions } =
|
||||
useFilterDefinitionsFromFilterableFieldMetadataItems();
|
||||
|
||||
const applyCurrentViewFiltersToCurrentRecordFilters = () => {
|
||||
const currentView = views.find((view) => view.id === currentViewId);
|
||||
|
||||
if (isDefined(currentView)) {
|
||||
setCurrentRecordFilters(
|
||||
mapViewFiltersToFilters(
|
||||
currentView.viewFilters,
|
||||
availableFilterDefinitions,
|
||||
),
|
||||
mapViewFiltersToFilters(currentView.viewFilters, filterDefinitions),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { useFilterDefinitionsFromFilterableFieldMetadataItems } from '@/object-record/record-filter/hooks/useFilterDefinitionsFromFilterableFieldMetadataItems';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
|
||||
import { ViewFilter } from '@/views/types/ViewFilter';
|
||||
import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters';
|
||||
|
||||
@ -10,16 +9,15 @@ export const useApplyViewFiltersToCurrentRecordFilters = () => {
|
||||
currentRecordFiltersComponentState,
|
||||
);
|
||||
|
||||
const availableFilterDefinitions = useRecoilComponentValueV2(
|
||||
availableFilterDefinitionsComponentState,
|
||||
);
|
||||
const { filterDefinitions } =
|
||||
useFilterDefinitionsFromFilterableFieldMetadataItems();
|
||||
|
||||
const applyViewFiltersToCurrentRecordFilters = (
|
||||
viewFilters: ViewFilter[],
|
||||
) => {
|
||||
const recordFiltersToApply = mapViewFiltersToFilters(
|
||||
viewFilters,
|
||||
availableFilterDefinitions,
|
||||
filterDefinitions,
|
||||
);
|
||||
|
||||
setCurrentRecordFilters(recordFiltersToApply);
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { availableFieldDefinitionsComponentState } from '@/views/states/availableFieldDefinitionsComponentState';
|
||||
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
|
||||
import { availableSortDefinitionsComponentState } from '@/views/states/availableSortDefinitionsComponentState';
|
||||
import { viewObjectMetadataIdComponentState } from '@/views/states/viewObjectMetadataIdComponentState';
|
||||
|
||||
@ -15,11 +14,6 @@ export const useInitViewBar = (viewBarInstanceId?: string) => {
|
||||
viewBarInstanceId,
|
||||
);
|
||||
|
||||
const setAvailableFilterDefinitions = useSetRecoilComponentStateV2(
|
||||
availableFilterDefinitionsComponentState,
|
||||
viewBarInstanceId,
|
||||
);
|
||||
|
||||
const setViewObjectMetadataId = useSetRecoilComponentStateV2(
|
||||
viewObjectMetadataIdComponentState,
|
||||
viewBarInstanceId,
|
||||
@ -28,7 +22,6 @@ export const useInitViewBar = (viewBarInstanceId?: string) => {
|
||||
return {
|
||||
setAvailableFieldDefinitions,
|
||||
setAvailableSortDefinitions,
|
||||
setAvailableFilterDefinitions,
|
||||
setViewObjectMetadataId,
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
import { RecordFilterDefinition } from '@/object-record/record-filter/types/RecordFilterDefinition';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
||||
|
||||
export const availableFilterDefinitionsComponentState = createComponentStateV2<
|
||||
RecordFilterDefinition[]
|
||||
>({
|
||||
key: 'availableFilterDefinitionsComponentState',
|
||||
defaultValue: [],
|
||||
componentInstanceContext: ViewComponentInstanceContext,
|
||||
});
|
||||
@ -0,0 +1,22 @@
|
||||
import { CurrentWorkspace } from '@/auth/states/currentWorkspaceState';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
||||
|
||||
export const checkIfFeatureFlagIsEnabledOnWorkspace = (
|
||||
featureKey: FeatureFlagKey | null | undefined,
|
||||
workspace: CurrentWorkspace | null | undefined,
|
||||
) => {
|
||||
if (
|
||||
!isDefined(featureKey) ||
|
||||
!isDefined(workspace) ||
|
||||
!isDefined(workspace.featureFlags)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const featureFlag = workspace.featureFlags.find(
|
||||
(flag) => flag.key === featureKey,
|
||||
);
|
||||
|
||||
return featureFlag?.value === true;
|
||||
};
|
||||
@ -3,9 +3,11 @@ import { ReactNode } from 'react';
|
||||
import { MutableSnapshot, RecoilRoot } from 'recoil';
|
||||
|
||||
import { RecordFiltersComponentInstanceContext } from '@/object-record/record-filter/states/context/RecordFiltersComponentInstanceContext';
|
||||
import { RecordIndexContextProvider } from '@/object-record/record-index/contexts/RecordIndexContext';
|
||||
import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope';
|
||||
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
||||
import { JestObjectMetadataItemSetter } from '~/testing/jest/JestObjectMetadataItemSetter';
|
||||
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
||||
|
||||
export const getJestMetadataAndApolloMocksWrapper = ({
|
||||
apolloMocks,
|
||||
@ -20,17 +22,31 @@ export const getJestMetadataAndApolloMocksWrapper = ({
|
||||
<RecoilRoot initializeState={onInitializeRecoilSnapshot}>
|
||||
<SnackBarProviderScope snackBarManagerScopeId="snack-bar-manager">
|
||||
<MockedProvider mocks={apolloMocks} addTypename={false}>
|
||||
<RecordFiltersComponentInstanceContext.Provider
|
||||
value={{ instanceId: 'instanceId' }}
|
||||
<RecordIndexContextProvider
|
||||
value={{
|
||||
indexIdentifierUrl: () => 'indexIdentifierUrl',
|
||||
onIndexRecordsLoaded: () => {},
|
||||
objectNamePlural: 'objectNamePlural',
|
||||
objectNameSingular: 'objectNameSingular',
|
||||
objectMetadataItem:
|
||||
generatedMockObjectMetadataItems.find(
|
||||
(item) => item.nameSingular === 'company',
|
||||
) ?? generatedMockObjectMetadataItems[0],
|
||||
recordIndexId: 'recordIndexId',
|
||||
}}
|
||||
>
|
||||
<ViewComponentInstanceContext.Provider
|
||||
<RecordFiltersComponentInstanceContext.Provider
|
||||
value={{ instanceId: 'instanceId' }}
|
||||
>
|
||||
<JestObjectMetadataItemSetter>
|
||||
{children}
|
||||
</JestObjectMetadataItemSetter>
|
||||
</ViewComponentInstanceContext.Provider>
|
||||
</RecordFiltersComponentInstanceContext.Provider>
|
||||
<ViewComponentInstanceContext.Provider
|
||||
value={{ instanceId: 'instanceId' }}
|
||||
>
|
||||
<JestObjectMetadataItemSetter>
|
||||
{children}
|
||||
</JestObjectMetadataItemSetter>
|
||||
</ViewComponentInstanceContext.Provider>
|
||||
</RecordFiltersComponentInstanceContext.Provider>
|
||||
</RecordIndexContextProvider>
|
||||
</MockedProvider>
|
||||
</SnackBarProviderScope>
|
||||
</RecoilRoot>
|
||||
|
||||
Reference in New Issue
Block a user