Clean record filter and record sort (#10466)
This PR removes what's left from record filter and record sort previous logic to handle CRUD and state management with view. So everything that is named combinedFilter and combinedSort is removed here. We implement currentRecordFilters and currentRecordSorts everywhere. We also remove the event in a state onSortSelectComponentState. (a pattern we want to avoid)
This commit is contained in:
@ -2,13 +2,13 @@ import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMeta
|
|||||||
import { availableFieldMetadataItemsForFilterFamilySelector } from '@/object-metadata/states/availableFieldMetadataItemsForFilterFamilySelector';
|
import { availableFieldMetadataItemsForFilterFamilySelector } from '@/object-metadata/states/availableFieldMetadataItemsForFilterFamilySelector';
|
||||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||||
import { useUpsertCombinedViewFilterGroup } from '@/object-record/advanced-filter/hooks/useUpsertCombinedViewFilterGroup';
|
import { useUpsertCombinedViewFilterGroup } from '@/object-record/advanced-filter/hooks/useUpsertCombinedViewFilterGroup';
|
||||||
|
import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter';
|
||||||
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
|
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
|
||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||||
import { ADVANCED_FILTER_DROPDOWN_ID } from '@/views/constants/AdvancedFilterDropdownId';
|
import { ADVANCED_FILTER_DROPDOWN_ID } from '@/views/constants/AdvancedFilterDropdownId';
|
||||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
||||||
import { useUpsertCombinedViewFilters } from '@/views/hooks/useUpsertCombinedViewFilters';
|
|
||||||
import { ViewFilterGroup } from '@/views/types/ViewFilterGroup';
|
import { ViewFilterGroup } from '@/views/types/ViewFilterGroup';
|
||||||
import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator';
|
import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
@ -31,7 +31,7 @@ export const AdvancedFilterAddFilterRuleSelect = ({
|
|||||||
const { currentViewId } = useGetCurrentView();
|
const { currentViewId } = useGetCurrentView();
|
||||||
|
|
||||||
const { upsertCombinedViewFilterGroup } = useUpsertCombinedViewFilterGroup();
|
const { upsertCombinedViewFilterGroup } = useUpsertCombinedViewFilterGroup();
|
||||||
const { upsertCombinedViewFilter } = useUpsertCombinedViewFilters();
|
const { upsertRecordFilter } = useUpsertRecordFilter();
|
||||||
|
|
||||||
const newPositionInViewFilterGroup = lastChildPosition + 1;
|
const newPositionInViewFilterGroup = lastChildPosition + 1;
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ export const AdvancedFilterAddFilterRuleSelect = ({
|
|||||||
defaultFieldMetadataItem.type,
|
defaultFieldMetadataItem.type,
|
||||||
);
|
);
|
||||||
|
|
||||||
upsertCombinedViewFilter({
|
upsertRecordFilter({
|
||||||
id: v4(),
|
id: v4(),
|
||||||
fieldMetadataId: defaultFieldMetadataItem.id,
|
fieldMetadataId: defaultFieldMetadataItem.id,
|
||||||
type: filterType,
|
type: filterType,
|
||||||
@ -124,7 +124,7 @@ export const AdvancedFilterAddFilterRuleSelect = ({
|
|||||||
defaultFieldMetadataItem.type,
|
defaultFieldMetadataItem.type,
|
||||||
);
|
);
|
||||||
|
|
||||||
upsertCombinedViewFilter({
|
upsertRecordFilter({
|
||||||
id: v4(),
|
id: v4(),
|
||||||
fieldMetadataId: defaultFieldMetadataItem.id,
|
fieldMetadataId: defaultFieldMetadataItem.id,
|
||||||
type: filterType,
|
type: filterType,
|
||||||
|
|||||||
@ -49,7 +49,7 @@ export const AdvancedFilterRootLevelViewFilterGroup = ({
|
|||||||
return (
|
return (
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
{childViewFiltersAndViewFilterGroups.map((child, i) =>
|
{childViewFiltersAndViewFilterGroups.map((child, i) =>
|
||||||
child.__typename === 'ViewFilterGroup' ? (
|
(child as any).__typename === 'ViewFilterGroup' ? (
|
||||||
<StyledRow key={child.id}>
|
<StyledRow key={child.id}>
|
||||||
<AdvancedFilterLogicalOperatorCell
|
<AdvancedFilterLogicalOperatorCell
|
||||||
index={i}
|
index={i}
|
||||||
|
|||||||
@ -1,11 +1,14 @@
|
|||||||
import { AdvancedFilterRuleOptionsDropdownButton } from '@/object-record/advanced-filter/components/AdvancedFilterRuleOptionsDropdownButton';
|
import { AdvancedFilterRuleOptionsDropdownButton } from '@/object-record/advanced-filter/components/AdvancedFilterRuleOptionsDropdownButton';
|
||||||
import { useCurrentViewFilter } from '@/object-record/advanced-filter/hooks/useCurrentViewFilter';
|
|
||||||
import { useCurrentViewViewFilterGroup } from '@/object-record/advanced-filter/hooks/useCurrentViewViewFilterGroup';
|
import { useCurrentViewViewFilterGroup } from '@/object-record/advanced-filter/hooks/useCurrentViewViewFilterGroup';
|
||||||
import { useDeleteCombinedViewFilterGroup } from '@/object-record/advanced-filter/hooks/useDeleteCombinedViewFilterGroup';
|
import { useDeleteCombinedViewFilterGroup } from '@/object-record/advanced-filter/hooks/useDeleteCombinedViewFilterGroup';
|
||||||
|
import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter';
|
||||||
|
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||||
|
|
||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { ADVANCED_FILTER_DROPDOWN_ID } from '@/views/constants/AdvancedFilterDropdownId';
|
import { ADVANCED_FILTER_DROPDOWN_ID } from '@/views/constants/AdvancedFilterDropdownId';
|
||||||
import { useDeleteCombinedViewFilters } from '@/views/hooks/useDeleteCombinedViewFilters';
|
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
import { MenuItem } from 'twenty-ui';
|
import { MenuItem } from 'twenty-ui';
|
||||||
|
|
||||||
@ -25,7 +28,7 @@ export const AdvancedFilterRuleOptionsDropdown = ({
|
|||||||
}: AdvancedFilterRuleOptionsDropdownProps) => {
|
}: AdvancedFilterRuleOptionsDropdownProps) => {
|
||||||
const dropdownId = `advanced-filter-rule-options-${viewFilterId ?? viewFilterGroupId}`;
|
const dropdownId = `advanced-filter-rule-options-${viewFilterId ?? viewFilterGroupId}`;
|
||||||
|
|
||||||
const { deleteCombinedViewFilter } = useDeleteCombinedViewFilters();
|
const { removeRecordFilter } = useRemoveRecordFilter();
|
||||||
const { deleteCombinedViewFilterGroup } = useDeleteCombinedViewFilterGroup();
|
const { deleteCombinedViewFilterGroup } = useDeleteCombinedViewFilterGroup();
|
||||||
|
|
||||||
const { currentViewFilterGroup, childViewFiltersAndViewFilterGroups } =
|
const { currentViewFilterGroup, childViewFiltersAndViewFilterGroups } =
|
||||||
@ -33,32 +36,37 @@ export const AdvancedFilterRuleOptionsDropdown = ({
|
|||||||
viewFilterGroupId,
|
viewFilterGroupId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const currentViewFilter = useCurrentViewFilter({
|
const currentRecordFilters = useRecoilComponentValueV2(
|
||||||
viewFilterId,
|
currentRecordFiltersComponentState,
|
||||||
});
|
);
|
||||||
|
|
||||||
|
const currentRecordFilter = currentRecordFilters.find(
|
||||||
|
(recordFilter) => recordFilter.id === viewFilterId,
|
||||||
|
);
|
||||||
|
|
||||||
const handleRemove = async () => {
|
const handleRemove = async () => {
|
||||||
if (isDefined(viewFilterId)) {
|
if (isDefined(viewFilterId)) {
|
||||||
deleteCombinedViewFilter(viewFilterId);
|
removeRecordFilter(viewFilterId);
|
||||||
|
|
||||||
const isOnlyViewFilterInGroup =
|
const isOnlyViewFilterInGroup =
|
||||||
childViewFiltersAndViewFilterGroups.length === 1;
|
childViewFiltersAndViewFilterGroups.length === 1;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
isOnlyViewFilterInGroup &&
|
isOnlyViewFilterInGroup &&
|
||||||
isDefined(currentViewFilter?.viewFilterGroupId)
|
isDefined(currentRecordFilter?.viewFilterGroupId)
|
||||||
) {
|
) {
|
||||||
deleteCombinedViewFilterGroup(currentViewFilter.viewFilterGroupId);
|
deleteCombinedViewFilterGroup(currentRecordFilter.viewFilterGroupId);
|
||||||
}
|
}
|
||||||
} else if (isDefined(currentViewFilterGroup)) {
|
} else if (isDefined(currentViewFilterGroup)) {
|
||||||
deleteCombinedViewFilterGroup(currentViewFilterGroup.id);
|
deleteCombinedViewFilterGroup(currentViewFilterGroup.id);
|
||||||
|
|
||||||
|
// TODO: This is a temporary fix view filter group will be removed soon.
|
||||||
const childViewFilters = childViewFiltersAndViewFilterGroups.filter(
|
const childViewFilters = childViewFiltersAndViewFilterGroups.filter(
|
||||||
(child) => child.__typename === 'ViewFilter',
|
(child) => (child as any).__typename === 'ViewFilter',
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const childViewFilter of childViewFilters) {
|
for (const childViewFilter of childViewFilters) {
|
||||||
await deleteCombinedViewFilter(childViewFilter.id);
|
removeRecordFilter(childViewFilter.id);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error('No view filter or view filter group to remove');
|
throw new Error('No view filter or view filter group to remove');
|
||||||
|
|||||||
@ -1,10 +1,13 @@
|
|||||||
import { AdvancedFilterViewFilterFieldSelect } from '@/object-record/advanced-filter/components/AdvancedFilterViewFilterFieldSelect';
|
import { AdvancedFilterViewFilterFieldSelect } from '@/object-record/advanced-filter/components/AdvancedFilterViewFilterFieldSelect';
|
||||||
import { AdvancedFilterViewFilterOperandSelect } from '@/object-record/advanced-filter/components/AdvancedFilterViewFilterOperandSelect';
|
import { AdvancedFilterViewFilterOperandSelect } from '@/object-record/advanced-filter/components/AdvancedFilterViewFilterOperandSelect';
|
||||||
import { AdvancedFilterViewFilterValueInput } from '@/object-record/advanced-filter/components/AdvancedFilterViewFilterValueInput';
|
import { AdvancedFilterViewFilterValueInput } from '@/object-record/advanced-filter/components/AdvancedFilterViewFilterValueInput';
|
||||||
import { useCurrentViewFilter } from '@/object-record/advanced-filter/hooks/useCurrentViewFilter';
|
|
||||||
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
|
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
|
||||||
import { configurableViewFilterOperands } from '@/object-record/object-filter-dropdown/utils/configurableViewFilterOperands';
|
import { configurableViewFilterOperands } from '@/object-record/object-filter-dropdown/utils/configurableViewFilterOperands';
|
||||||
|
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
import { isDefined } from 'twenty-shared';
|
||||||
|
|
||||||
const StyledValueDropdownContainer = styled.div`
|
const StyledValueDropdownContainer = styled.div`
|
||||||
flex: 3;
|
flex: 3;
|
||||||
@ -25,22 +28,30 @@ type AdvancedFilterViewFilterProps = {
|
|||||||
export const AdvancedFilterViewFilter = ({
|
export const AdvancedFilterViewFilter = ({
|
||||||
viewFilterId,
|
viewFilterId,
|
||||||
}: AdvancedFilterViewFilterProps) => {
|
}: AdvancedFilterViewFilterProps) => {
|
||||||
const filter = useCurrentViewFilter({ viewFilterId });
|
const currentRecordFilters = useRecoilComponentValueV2(
|
||||||
|
currentRecordFiltersComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
if (!filter) {
|
const recordFilter = currentRecordFilters.find(
|
||||||
|
(recordFilter) => recordFilter.id === viewFilterId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isDefined(recordFilter)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ObjectFilterDropdownComponentInstanceContext.Provider
|
<ObjectFilterDropdownComponentInstanceContext.Provider
|
||||||
value={{ instanceId: filter.id }}
|
value={{ instanceId: recordFilter.id }}
|
||||||
>
|
>
|
||||||
<StyledRow>
|
<StyledRow>
|
||||||
<AdvancedFilterViewFilterFieldSelect viewFilterId={filter.id} />
|
<AdvancedFilterViewFilterFieldSelect viewFilterId={recordFilter.id} />
|
||||||
<AdvancedFilterViewFilterOperandSelect viewFilterId={filter.id} />
|
<AdvancedFilterViewFilterOperandSelect viewFilterId={recordFilter.id} />
|
||||||
<StyledValueDropdownContainer>
|
<StyledValueDropdownContainer>
|
||||||
{configurableViewFilterOperands.has(filter.operand) && (
|
{configurableViewFilterOperands.has(recordFilter.operand) && (
|
||||||
<AdvancedFilterViewFilterValueInput viewFilterId={filter.id} />
|
<AdvancedFilterViewFilterValueInput
|
||||||
|
viewFilterId={recordFilter.id}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</StyledValueDropdownContainer>
|
</StyledValueDropdownContainer>
|
||||||
</StyledRow>
|
</StyledRow>
|
||||||
|
|||||||
@ -1,13 +1,15 @@
|
|||||||
import { useAdvancedFilterDropdown } from '@/object-record/advanced-filter/hooks/useAdvancedFilterDropdown';
|
import { useAdvancedFilterDropdown } from '@/object-record/advanced-filter/hooks/useAdvancedFilterDropdown';
|
||||||
import { useCurrentViewFilter } from '@/object-record/advanced-filter/hooks/useCurrentViewFilter';
|
|
||||||
import { ObjectFilterDropdownFilterSelect } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelect';
|
import { ObjectFilterDropdownFilterSelect } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelect';
|
||||||
import { ObjectFilterDropdownFilterSelectCompositeFieldSubMenu } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectCompositeFieldSubMenu';
|
import { ObjectFilterDropdownFilterSelectCompositeFieldSubMenu } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectCompositeFieldSubMenu';
|
||||||
import { advancedFilterViewFilterGroupIdComponentState } from '@/object-record/object-filter-dropdown/states/advancedFilterViewFilterGroupIdComponentState';
|
import { advancedFilterViewFilterGroupIdComponentState } from '@/object-record/object-filter-dropdown/states/advancedFilterViewFilterGroupIdComponentState';
|
||||||
import { advancedFilterViewFilterIdComponentState } from '@/object-record/object-filter-dropdown/states/advancedFilterViewFilterIdComponentState';
|
import { advancedFilterViewFilterIdComponentState } from '@/object-record/object-filter-dropdown/states/advancedFilterViewFilterIdComponentState';
|
||||||
import { objectFilterDropdownIsSelectingCompositeFieldComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownIsSelectingCompositeFieldComponentState';
|
import { objectFilterDropdownIsSelectingCompositeFieldComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownIsSelectingCompositeFieldComponentState';
|
||||||
|
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||||
import { SelectControl } from '@/ui/input/components/SelectControl';
|
import { SelectControl } from '@/ui/input/components/SelectControl';
|
||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2';
|
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||||
import { ADVANCED_FILTER_DROPDOWN_ID } from '@/views/constants/AdvancedFilterDropdownId';
|
import { ADVANCED_FILTER_DROPDOWN_ID } from '@/views/constants/AdvancedFilterDropdownId';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
@ -25,7 +27,13 @@ export const AdvancedFilterViewFilterFieldSelect = ({
|
|||||||
}: AdvancedFilterViewFilterFieldSelectProps) => {
|
}: AdvancedFilterViewFilterFieldSelectProps) => {
|
||||||
const { advancedFilterDropdownId } = useAdvancedFilterDropdown(viewFilterId);
|
const { advancedFilterDropdownId } = useAdvancedFilterDropdown(viewFilterId);
|
||||||
|
|
||||||
const recordFilter = useCurrentViewFilter({ viewFilterId });
|
const currentRecordFilters = useRecoilComponentValueV2(
|
||||||
|
currentRecordFiltersComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const recordFilter = currentRecordFilters.find(
|
||||||
|
(recordFilter) => recordFilter.id === viewFilterId,
|
||||||
|
);
|
||||||
|
|
||||||
const selectedFieldLabel = recordFilter?.label ?? '';
|
const selectedFieldLabel = recordFilter?.label ?? '';
|
||||||
|
|
||||||
|
|||||||
@ -1,15 +1,17 @@
|
|||||||
import { useGetFieldMetadataItemById } from '@/object-metadata/hooks/useGetFieldMetadataItemById';
|
import { useGetFieldMetadataItemById } from '@/object-metadata/hooks/useGetFieldMetadataItemById';
|
||||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||||
import { useCurrentViewFilter } from '@/object-record/advanced-filter/hooks/useCurrentViewFilter';
|
|
||||||
import { getInitialFilterValue } from '@/object-record/object-filter-dropdown/utils/getInitialFilterValue';
|
import { getInitialFilterValue } from '@/object-record/object-filter-dropdown/utils/getInitialFilterValue';
|
||||||
import { getOperandLabel } from '@/object-record/object-filter-dropdown/utils/getOperandLabel';
|
import { getOperandLabel } from '@/object-record/object-filter-dropdown/utils/getOperandLabel';
|
||||||
|
import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter';
|
||||||
|
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||||
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
|
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
|
||||||
import { SelectControl } from '@/ui/input/components/SelectControl';
|
import { SelectControl } from '@/ui/input/components/SelectControl';
|
||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
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 { ADVANCED_FILTER_DROPDOWN_ID } from '@/views/constants/AdvancedFilterDropdownId';
|
||||||
import { useUpsertCombinedViewFilters } from '@/views/hooks/useUpsertCombinedViewFilters';
|
|
||||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
@ -28,7 +30,13 @@ export const AdvancedFilterViewFilterOperandSelect = ({
|
|||||||
}: AdvancedFilterViewFilterOperandSelectProps) => {
|
}: AdvancedFilterViewFilterOperandSelectProps) => {
|
||||||
const dropdownId = `advanced-filter-view-filter-operand-${viewFilterId}`;
|
const dropdownId = `advanced-filter-view-filter-operand-${viewFilterId}`;
|
||||||
|
|
||||||
const filter = useCurrentViewFilter({ viewFilterId });
|
const currentRecordFilters = useRecoilComponentValueV2(
|
||||||
|
currentRecordFiltersComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const filter = currentRecordFilters.find(
|
||||||
|
(recordFilter) => recordFilter.id === viewFilterId,
|
||||||
|
);
|
||||||
|
|
||||||
const { getFieldMetadataItemById } = useGetFieldMetadataItemById();
|
const { getFieldMetadataItemById } = useGetFieldMetadataItemById();
|
||||||
|
|
||||||
@ -36,7 +44,7 @@ export const AdvancedFilterViewFilterOperandSelect = ({
|
|||||||
|
|
||||||
const { closeDropdown } = useDropdown(dropdownId);
|
const { closeDropdown } = useDropdown(dropdownId);
|
||||||
|
|
||||||
const { upsertCombinedViewFilter } = useUpsertCombinedViewFilters();
|
const { upsertRecordFilter } = useUpsertRecordFilter();
|
||||||
|
|
||||||
const handleOperandChange = (operand: ViewFilterOperand) => {
|
const handleOperandChange = (operand: ViewFilterOperand) => {
|
||||||
closeDropdown();
|
closeDropdown();
|
||||||
@ -60,7 +68,7 @@ export const AdvancedFilterViewFilterOperandSelect = ({
|
|||||||
filter.displayValue,
|
filter.displayValue,
|
||||||
);
|
);
|
||||||
|
|
||||||
upsertCombinedViewFilter({
|
upsertRecordFilter({
|
||||||
...filter,
|
...filter,
|
||||||
operand,
|
operand,
|
||||||
value,
|
value,
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
import { useCurrentViewFilter } from '@/object-record/advanced-filter/hooks/useCurrentViewFilter';
|
|
||||||
import { ObjectFilterDropdownFilterInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterInput';
|
import { ObjectFilterDropdownFilterInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterInput';
|
||||||
import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState';
|
import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemIdUsedInDropdownComponentState';
|
||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||||
|
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||||
import { SelectControl } from '@/ui/input/components/SelectControl';
|
import { SelectControl } from '@/ui/input/components/SelectControl';
|
||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||||
import { ADVANCED_FILTER_DROPDOWN_ID } from '@/views/constants/AdvancedFilterDropdownId';
|
import { ADVANCED_FILTER_DROPDOWN_ID } from '@/views/constants/AdvancedFilterDropdownId';
|
||||||
|
|
||||||
@ -18,7 +19,13 @@ export const AdvancedFilterViewFilterValueInput = ({
|
|||||||
}: AdvancedFilterViewFilterValueInputProps) => {
|
}: AdvancedFilterViewFilterValueInputProps) => {
|
||||||
const dropdownId = `advanced-filter-view-filter-value-input-${viewFilterId}`;
|
const dropdownId = `advanced-filter-view-filter-value-input-${viewFilterId}`;
|
||||||
|
|
||||||
const filter = useCurrentViewFilter({ viewFilterId });
|
const currentRecordFilters = useRecoilComponentValueV2(
|
||||||
|
currentRecordFiltersComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const filter = currentRecordFilters.find(
|
||||||
|
(recordFilter) => recordFilter.id === viewFilterId,
|
||||||
|
);
|
||||||
|
|
||||||
const isDisabled = !filter?.fieldMetadataId || !filter.operand;
|
const isDisabled = !filter?.fieldMetadataId || !filter.operand;
|
||||||
|
|
||||||
|
|||||||
@ -1,29 +0,0 @@
|
|||||||
import { useFilterableFieldMetadataItemsInRecordIndexContext } from '@/object-record/record-filter/hooks/useFilterableFieldMetadataItemsInRecordIndexContext';
|
|
||||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
|
||||||
import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters';
|
|
||||||
|
|
||||||
export const useCurrentViewFilter = ({
|
|
||||||
viewFilterId,
|
|
||||||
}: {
|
|
||||||
viewFilterId?: string;
|
|
||||||
}) => {
|
|
||||||
const { filterableFieldMetadataItems } =
|
|
||||||
useFilterableFieldMetadataItemsInRecordIndexContext();
|
|
||||||
|
|
||||||
const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView();
|
|
||||||
|
|
||||||
const viewFilter = currentViewWithCombinedFiltersAndSorts?.viewFilters.find(
|
|
||||||
(viewFilter) => viewFilter.id === viewFilterId,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!viewFilter) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const [filter] = mapViewFiltersToFilters(
|
|
||||||
[viewFilter],
|
|
||||||
filterableFieldMetadataItems,
|
|
||||||
);
|
|
||||||
|
|
||||||
return filter;
|
|
||||||
};
|
|
||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
||||||
import { ViewFilter } from '@/views/types/ViewFilter';
|
import { ViewFilter } from '@/views/types/ViewFilter';
|
||||||
import { ViewFilterGroup } from '@/views/types/ViewFilterGroup';
|
import { ViewFilterGroup } from '@/views/types/ViewFilterGroup';
|
||||||
@ -10,6 +12,10 @@ export const useCurrentViewViewFilterGroup = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView();
|
const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView();
|
||||||
|
|
||||||
|
const currentRecordFilters = useRecoilComponentValueV2(
|
||||||
|
currentRecordFiltersComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
const viewFilterGroup =
|
const viewFilterGroup =
|
||||||
currentViewWithCombinedFiltersAndSorts?.viewFilterGroups.find(
|
currentViewWithCombinedFiltersAndSorts?.viewFilterGroups.find(
|
||||||
(viewFilterGroup) => viewFilterGroup.id === viewFilterGroupId,
|
(viewFilterGroup) => viewFilterGroup.id === viewFilterGroupId,
|
||||||
@ -25,11 +31,10 @@ export const useCurrentViewViewFilterGroup = ({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const childViewFilters =
|
const childRecordFilters = currentRecordFilters.filter(
|
||||||
currentViewWithCombinedFiltersAndSorts?.viewFilters.filter(
|
(recordFilterToFilter) =>
|
||||||
(viewFilterToFilter) =>
|
recordFilterToFilter.viewFilterGroupId === viewFilterGroup.id,
|
||||||
viewFilterToFilter.viewFilterGroupId === viewFilterGroup.id,
|
);
|
||||||
);
|
|
||||||
|
|
||||||
const childViewFilterGroups =
|
const childViewFilterGroups =
|
||||||
currentViewWithCombinedFiltersAndSorts?.viewFilterGroups.filter(
|
currentViewWithCombinedFiltersAndSorts?.viewFilterGroups.filter(
|
||||||
@ -39,7 +44,7 @@ export const useCurrentViewViewFilterGroup = ({
|
|||||||
|
|
||||||
const childViewFiltersAndViewFilterGroups = [
|
const childViewFiltersAndViewFilterGroups = [
|
||||||
...(childViewFilterGroups ?? []),
|
...(childViewFilterGroups ?? []),
|
||||||
...(childViewFilters ?? []),
|
...(childRecordFilters ?? []),
|
||||||
].sort((a, b) => {
|
].sort((a, b) => {
|
||||||
const positionA = a.positionInViewFilterGroup ?? 0;
|
const positionA = a.positionInViewFilterGroup ?? 0;
|
||||||
const positionB = b.positionInViewFilterGroup ?? 0;
|
const positionB = b.positionInViewFilterGroup ?? 0;
|
||||||
|
|||||||
@ -3,12 +3,12 @@ import { availableFieldMetadataItemsForFilterFamilySelector } from '@/object-met
|
|||||||
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||||
import { useUpsertCombinedViewFilterGroup } from '@/object-record/advanced-filter/hooks/useUpsertCombinedViewFilterGroup';
|
import { useUpsertCombinedViewFilterGroup } from '@/object-record/advanced-filter/hooks/useUpsertCombinedViewFilterGroup';
|
||||||
import { OBJECT_FILTER_DROPDOWN_ID } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId';
|
import { OBJECT_FILTER_DROPDOWN_ID } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId';
|
||||||
|
import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter';
|
||||||
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
|
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
|
||||||
|
|
||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||||
import { ADVANCED_FILTER_DROPDOWN_ID } from '@/views/constants/AdvancedFilterDropdownId';
|
import { ADVANCED_FILTER_DROPDOWN_ID } from '@/views/constants/AdvancedFilterDropdownId';
|
||||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
||||||
import { useUpsertCombinedViewFilters } from '@/views/hooks/useUpsertCombinedViewFilters';
|
|
||||||
import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator';
|
import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useLingui } from '@lingui/react/macro';
|
import { useLingui } from '@lingui/react/macro';
|
||||||
@ -59,7 +59,7 @@ export const AdvancedFilterButton = () => {
|
|||||||
|
|
||||||
const { upsertCombinedViewFilterGroup } = useUpsertCombinedViewFilterGroup();
|
const { upsertCombinedViewFilterGroup } = useUpsertCombinedViewFilterGroup();
|
||||||
|
|
||||||
const { upsertCombinedViewFilter } = useUpsertCombinedViewFilters();
|
const { upsertRecordFilter } = useUpsertRecordFilter();
|
||||||
|
|
||||||
const objectMetadataId =
|
const objectMetadataId =
|
||||||
currentViewWithCombinedFiltersAndSorts?.objectMetadataId;
|
currentViewWithCombinedFiltersAndSorts?.objectMetadataId;
|
||||||
@ -115,7 +115,7 @@ export const AdvancedFilterButton = () => {
|
|||||||
filterType,
|
filterType,
|
||||||
})[0];
|
})[0];
|
||||||
|
|
||||||
upsertCombinedViewFilter({
|
upsertRecordFilter({
|
||||||
id: v4(),
|
id: v4(),
|
||||||
fieldMetadataId: defaultFieldMetadataItem.id,
|
fieldMetadataId: defaultFieldMetadataItem.id,
|
||||||
operand: firstOperand,
|
operand: firstOperand,
|
||||||
|
|||||||
@ -11,13 +11,14 @@ import { objectFilterDropdownSelectedRecordIdsComponentState } from '@/object-re
|
|||||||
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
import { selectedFilterComponentState } from '@/object-record/object-filter-dropdown/states/selectedFilterComponentState';
|
||||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
||||||
|
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||||
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
import { MultipleSelectDropdown } from '@/object-record/select/components/MultipleSelectDropdown';
|
import { MultipleSelectDropdown } from '@/object-record/select/components/MultipleSelectDropdown';
|
||||||
import { useRecordsForSelect } from '@/object-record/select/hooks/useRecordsForSelect';
|
import { useRecordsForSelect } from '@/object-record/select/hooks/useRecordsForSelect';
|
||||||
import { SelectableItem } from '@/object-record/select/types/SelectableItem';
|
import { SelectableItem } from '@/object-record/select/types/SelectableItem';
|
||||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||||
import { RelationFilterValue } from '@/views/view-filter-value/types/RelationFilterValue';
|
import { RelationFilterValue } from '@/views/view-filter-value/types/RelationFilterValue';
|
||||||
import { jsonRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/jsonRelationFilterValueSchema';
|
import { jsonRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/jsonRelationFilterValueSchema';
|
||||||
import { simpleRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/simpleRelationFilterValueSchema';
|
import { simpleRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/simpleRelationFilterValueSchema';
|
||||||
@ -59,10 +60,11 @@ export const ObjectFilterDropdownRecordSelect = ({
|
|||||||
objectFilterDropdownSelectedRecordIdsComponentState,
|
objectFilterDropdownSelectedRecordIdsComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { applyRecordFilter } = useApplyRecordFilter(viewComponentId);
|
const setObjectFilterDropdownSelectedRecordIds = useSetRecoilComponentStateV2(
|
||||||
|
objectFilterDropdownSelectedRecordIdsComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
const { currentViewWithCombinedFiltersAndSorts } =
|
const { applyRecordFilter } = useApplyRecordFilter(viewComponentId);
|
||||||
useGetCurrentView(viewComponentId);
|
|
||||||
|
|
||||||
const { isCurrentWorkspaceMemberSelected } = jsonRelationFilterValueSchema
|
const { isCurrentWorkspaceMemberSelected } = jsonRelationFilterValueSchema
|
||||||
.catch({
|
.catch({
|
||||||
@ -121,6 +123,10 @@ export const ObjectFilterDropdownRecordSelect = ({
|
|||||||
.includes(objectFilterDropdownSearchInput.toLowerCase()),
|
.includes(objectFilterDropdownSearchInput.toLowerCase()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const currentRecordFilters = useRecoilComponentValueV2(
|
||||||
|
currentRecordFiltersComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
const handleMultipleRecordSelectChange = (
|
const handleMultipleRecordSelectChange = (
|
||||||
itemToSelect: SelectableItem,
|
itemToSelect: SelectableItem,
|
||||||
isNewSelectedValue: boolean,
|
isNewSelectedValue: boolean,
|
||||||
@ -136,6 +142,7 @@ export const ObjectFilterDropdownRecordSelect = ({
|
|||||||
...objectFilterDropdownSelectedRecordIds,
|
...objectFilterDropdownSelectedRecordIds,
|
||||||
itemToSelect.id,
|
itemToSelect.id,
|
||||||
];
|
];
|
||||||
|
|
||||||
const selectedRecordIdsWithRemovedRecord =
|
const selectedRecordIdsWithRemovedRecord =
|
||||||
objectFilterDropdownSelectedRecordIds.filter(
|
objectFilterDropdownSelectedRecordIds.filter(
|
||||||
(id) => id !== itemToSelect.id,
|
(id) => id !== itemToSelect.id,
|
||||||
@ -187,14 +194,15 @@ export const ObjectFilterDropdownRecordSelect = ({
|
|||||||
} satisfies RelationFilterValue)
|
} satisfies RelationFilterValue)
|
||||||
: '';
|
: '';
|
||||||
|
|
||||||
const viewFilter =
|
const recordFilterInDropdown = currentRecordFilters.find(
|
||||||
currentViewWithCombinedFiltersAndSorts?.viewFilters.find(
|
(recordFilter) =>
|
||||||
(viewFilter) =>
|
recordFilter.fieldMetadataId ===
|
||||||
viewFilter.fieldMetadataId ===
|
fieldMetadataItemUsedInFilterDropdown.id,
|
||||||
fieldMetadataItemUsedInFilterDropdown.id,
|
);
|
||||||
);
|
|
||||||
|
|
||||||
const filterId = viewFilter?.id ?? v4();
|
setObjectFilterDropdownSelectedRecordIds(newSelectedRecordIds);
|
||||||
|
|
||||||
|
const filterId = recordFilterInDropdown?.id ?? v4();
|
||||||
|
|
||||||
applyRecordFilter({
|
applyRecordFilter({
|
||||||
id: selectedFilter?.id ? selectedFilter.id : filterId,
|
id: selectedFilter?.id ? selectedFilter.id : filterId,
|
||||||
|
|||||||
@ -11,13 +11,12 @@ import { selectedOperandInDropdownComponentState } from '@/object-record/object-
|
|||||||
import { getActorSourceMultiSelectOptions } from '@/object-record/object-filter-dropdown/utils/getActorSourceMultiSelectOptions';
|
import { getActorSourceMultiSelectOptions } from '@/object-record/object-filter-dropdown/utils/getActorSourceMultiSelectOptions';
|
||||||
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
import { useApplyRecordFilter } from '@/object-record/record-filter/hooks/useApplyRecordFilter';
|
||||||
import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter';
|
import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter';
|
||||||
|
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||||
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
import { MultipleSelectDropdown } from '@/object-record/select/components/MultipleSelectDropdown';
|
import { MultipleSelectDropdown } from '@/object-record/select/components/MultipleSelectDropdown';
|
||||||
import { SelectableItem } from '@/object-record/select/types/SelectableItem';
|
import { SelectableItem } from '@/object-record/select/types/SelectableItem';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||||
import { useDeleteCombinedViewFilters } from '@/views/hooks/useDeleteCombinedViewFilters';
|
|
||||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
|
||||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
|
|
||||||
@ -57,12 +56,6 @@ export const ObjectFilterDropdownSourceSelect = ({
|
|||||||
|
|
||||||
const { applyRecordFilter } = useApplyRecordFilter(viewComponentId);
|
const { applyRecordFilter } = useApplyRecordFilter(viewComponentId);
|
||||||
|
|
||||||
const { deleteCombinedViewFilter } =
|
|
||||||
useDeleteCombinedViewFilters(viewComponentId);
|
|
||||||
|
|
||||||
const { currentViewWithCombinedFiltersAndSorts } =
|
|
||||||
useGetCurrentView(viewComponentId);
|
|
||||||
|
|
||||||
// TODO: this should be removed as it is not consistent across re-renders
|
// TODO: this should be removed as it is not consistent across re-renders
|
||||||
const [fieldId] = useState(v4());
|
const [fieldId] = useState(v4());
|
||||||
|
|
||||||
@ -78,6 +71,10 @@ export const ObjectFilterDropdownSourceSelect = ({
|
|||||||
|
|
||||||
const { removeRecordFilter } = useRemoveRecordFilter();
|
const { removeRecordFilter } = useRemoveRecordFilter();
|
||||||
|
|
||||||
|
const currentRecordFilters = useRecoilComponentValueV2(
|
||||||
|
currentRecordFiltersComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
const handleMultipleItemSelectChange = (
|
const handleMultipleItemSelectChange = (
|
||||||
itemToSelect: SelectableItem,
|
itemToSelect: SelectableItem,
|
||||||
newSelectedValue: boolean,
|
newSelectedValue: boolean,
|
||||||
@ -97,7 +94,7 @@ export const ObjectFilterDropdownSourceSelect = ({
|
|||||||
if (newSelectedItemIds.length === 0) {
|
if (newSelectedItemIds.length === 0) {
|
||||||
emptyRecordFilter();
|
emptyRecordFilter();
|
||||||
removeRecordFilter(fieldMetadataItemUsedInFilterDropdown.id);
|
removeRecordFilter(fieldMetadataItemUsedInFilterDropdown.id);
|
||||||
deleteCombinedViewFilter(fieldId);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,14 +118,13 @@ export const ObjectFilterDropdownSourceSelect = ({
|
|||||||
? JSON.stringify(newSelectedItemIds)
|
? JSON.stringify(newSelectedItemIds)
|
||||||
: EMPTY_FILTER_VALUE;
|
: EMPTY_FILTER_VALUE;
|
||||||
|
|
||||||
const viewFilter =
|
const recordFilter = currentRecordFilters.find(
|
||||||
currentViewWithCombinedFiltersAndSorts?.viewFilters.find(
|
(recordFilter) =>
|
||||||
(viewFilter) =>
|
recordFilter.fieldMetadataId ===
|
||||||
viewFilter.fieldMetadataId ===
|
fieldMetadataItemUsedInFilterDropdown.id,
|
||||||
fieldMetadataItemUsedInFilterDropdown.id,
|
);
|
||||||
);
|
|
||||||
|
|
||||||
const filterId = viewFilter?.id ?? fieldId;
|
const filterId = recordFilter?.id ?? fieldId;
|
||||||
|
|
||||||
applyRecordFilter({
|
applyRecordFilter({
|
||||||
id: selectedFilter?.id ? selectedFilter.id : filterId,
|
id: selectedFilter?.id ? selectedFilter.id : filterId,
|
||||||
|
|||||||
@ -10,9 +10,9 @@ import { useResetSortDropdown } from '@/object-record/object-sort-dropdown/hooks
|
|||||||
import { useToggleSortDropdown } from '@/object-record/object-sort-dropdown/hooks/useToggleSortDropdown';
|
import { useToggleSortDropdown } from '@/object-record/object-sort-dropdown/hooks/useToggleSortDropdown';
|
||||||
import { isRecordSortDirectionDropdownMenuUnfoldedComponentState } from '@/object-record/object-sort-dropdown/states/isRecordSortDirectionDropdownMenuUnfoldedComponentState';
|
import { isRecordSortDirectionDropdownMenuUnfoldedComponentState } from '@/object-record/object-sort-dropdown/states/isRecordSortDirectionDropdownMenuUnfoldedComponentState';
|
||||||
import { objectSortDropdownSearchInputComponentState } from '@/object-record/object-sort-dropdown/states/objectSortDropdownSearchInputComponentState';
|
import { objectSortDropdownSearchInputComponentState } from '@/object-record/object-sort-dropdown/states/objectSortDropdownSearchInputComponentState';
|
||||||
import { onSortSelectComponentState } from '@/object-record/object-sort-dropdown/states/onSortSelectScopedState';
|
|
||||||
import { selectedRecordSortDirectionComponentState } from '@/object-record/object-sort-dropdown/states/selectedRecordSortDirectionComponentState';
|
import { selectedRecordSortDirectionComponentState } from '@/object-record/object-sort-dropdown/states/selectedRecordSortDirectionComponentState';
|
||||||
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
||||||
|
import { useUpsertRecordSort } from '@/object-record/record-sort/hooks/useUpsertRecordSort';
|
||||||
import {
|
import {
|
||||||
RECORD_SORT_DIRECTIONS,
|
RECORD_SORT_DIRECTIONS,
|
||||||
RecordSortDirection,
|
RecordSortDirection,
|
||||||
@ -159,12 +159,12 @@ export const ObjectSortDropdownButton = ({
|
|||||||
|
|
||||||
const { closeSortDropdown } = useCloseSortDropdown();
|
const { closeSortDropdown } = useCloseSortDropdown();
|
||||||
|
|
||||||
const onSortSelect = useRecoilComponentValueV2(onSortSelectComponentState);
|
const { upsertRecordSort } = useUpsertRecordSort();
|
||||||
|
|
||||||
const handleAddSort = (fieldMetadataItem: FieldMetadataItem) => {
|
const handleAddSort = (fieldMetadataItem: FieldMetadataItem) => {
|
||||||
setObjectSortDropdownSearchInput('');
|
setObjectSortDropdownSearchInput('');
|
||||||
closeSortDropdown();
|
closeSortDropdown();
|
||||||
onSortSelect?.({
|
upsertRecordSort({
|
||||||
id: v4(),
|
id: v4(),
|
||||||
fieldMetadataId: fieldMetadataItem.id,
|
fieldMetadataId: fieldMetadataItem.id,
|
||||||
direction: selectedRecordSortDirection,
|
direction: selectedRecordSortDirection,
|
||||||
|
|||||||
@ -1,9 +0,0 @@
|
|||||||
import { ObjectSortDropdownComponentInstanceContext } from '@/object-record/object-sort-dropdown/states/context/ObjectSortDropdownComponentInstanceContext';
|
|
||||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
|
||||||
|
|
||||||
export const isRecordSortSelectedComponentState =
|
|
||||||
createComponentStateV2<boolean>({
|
|
||||||
key: 'isRecordSortSelectedComponentState',
|
|
||||||
defaultValue: false,
|
|
||||||
componentInstanceContext: ObjectSortDropdownComponentInstanceContext,
|
|
||||||
});
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
import { ObjectSortDropdownComponentInstanceContext } from '@/object-record/object-sort-dropdown/states/context/ObjectSortDropdownComponentInstanceContext';
|
|
||||||
import { RecordSort } from '@/object-record/record-sort/types/RecordSort';
|
|
||||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
|
||||||
|
|
||||||
export const onSortSelectComponentState = createComponentStateV2<
|
|
||||||
((sort: RecordSort) => void) | undefined
|
|
||||||
>({
|
|
||||||
key: 'onSortSelectComponentState',
|
|
||||||
defaultValue: undefined,
|
|
||||||
componentInstanceContext: ObjectSortDropdownComponentInstanceContext,
|
|
||||||
});
|
|
||||||
@ -2,12 +2,11 @@ import { selectedFilterComponentState } from '@/object-record/object-filter-drop
|
|||||||
import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter';
|
import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter';
|
||||||
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||||
import { useUpsertCombinedViewFilters } from '@/views/hooks/useUpsertCombinedViewFilters';
|
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
|
|
||||||
export const useApplyRecordFilter = (componentInstanceId?: string) => {
|
export const useApplyRecordFilter = (componentInstanceId?: string) => {
|
||||||
const { upsertCombinedViewFilter } = useUpsertCombinedViewFilters();
|
|
||||||
const selectedFilterCallbackState = useRecoilComponentCallbackStateV2(
|
const selectedFilterCallbackState = useRecoilComponentCallbackStateV2(
|
||||||
selectedFilterComponentState,
|
selectedFilterComponentState,
|
||||||
componentInstanceId,
|
componentInstanceId,
|
||||||
@ -21,11 +20,10 @@ export const useApplyRecordFilter = (componentInstanceId?: string) => {
|
|||||||
set(selectedFilterCallbackState, filter);
|
set(selectedFilterCallbackState, filter);
|
||||||
|
|
||||||
if (isDefined(filter)) {
|
if (isDefined(filter)) {
|
||||||
upsertCombinedViewFilter(filter);
|
|
||||||
upsertRecordFilter(filter);
|
upsertRecordFilter(filter);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[selectedFilterCallbackState, upsertCombinedViewFilter, upsertRecordFilter],
|
[selectedFilterCallbackState, upsertRecordFilter],
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -51,7 +51,7 @@ export const RecordIndexBoardContainer = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RecordBoard />
|
<RecordBoard />
|
||||||
<RecordIndexRemoveSortingModal recordIndexId={recordBoardId} />
|
<RecordIndexRemoveSortingModal />
|
||||||
</RecordBoardContext.Provider>
|
</RecordBoardContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,33 +1,26 @@
|
|||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { useRemoveRecordSort } from '@/object-record/record-sort/hooks/useRemoveRecordSort';
|
import { useRemoveRecordSort } from '@/object-record/record-sort/hooks/useRemoveRecordSort';
|
||||||
|
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
|
||||||
import { isRemoveSortingModalOpenState } from '@/object-record/record-table/states/isRemoveSortingModalOpenState';
|
import { isRemoveSortingModalOpenState } from '@/object-record/record-table/states/isRemoveSortingModalOpenState';
|
||||||
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
|
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
|
||||||
import { useDeleteCombinedViewSorts } from '@/views/hooks/useDeleteCombinedViewSorts';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
|
||||||
|
|
||||||
export const RecordIndexRemoveSortingModal = ({
|
export const RecordIndexRemoveSortingModal = () => {
|
||||||
recordIndexId,
|
const currentRecordSorts = useRecoilComponentValueV2(
|
||||||
}: {
|
currentRecordSortsComponentState,
|
||||||
recordIndexId: string;
|
);
|
||||||
}) => {
|
|
||||||
const { currentViewWithCombinedFiltersAndSorts } =
|
|
||||||
useGetCurrentView(recordIndexId);
|
|
||||||
|
|
||||||
const viewSorts = currentViewWithCombinedFiltersAndSorts?.viewSorts || [];
|
const fieldMetadataIds = currentRecordSorts.map(
|
||||||
const fieldMetadataIds = viewSorts.map(
|
|
||||||
(viewSort) => viewSort.fieldMetadataId,
|
(viewSort) => viewSort.fieldMetadataId,
|
||||||
);
|
);
|
||||||
const [isRemoveSortingModalOpen, setIsRemoveSortingModalOpen] =
|
const [isRemoveSortingModalOpen, setIsRemoveSortingModalOpen] =
|
||||||
useRecoilState(isRemoveSortingModalOpenState);
|
useRecoilState(isRemoveSortingModalOpenState);
|
||||||
|
|
||||||
const { deleteCombinedViewSort } = useDeleteCombinedViewSorts(recordIndexId);
|
|
||||||
|
|
||||||
const { removeRecordSort } = useRemoveRecordSort();
|
const { removeRecordSort } = useRemoveRecordSort();
|
||||||
|
|
||||||
const handleRemoveClick = () => {
|
const handleRemoveClick = () => {
|
||||||
fieldMetadataIds.forEach((id) => {
|
fieldMetadataIds.forEach((id) => {
|
||||||
deleteCombinedViewSort(id);
|
|
||||||
removeRecordSort(id);
|
removeRecordSort(id);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@ -34,7 +34,7 @@ export const RecordIndexTableContainer = ({
|
|||||||
viewBarId={viewBarId}
|
viewBarId={viewBarId}
|
||||||
updateRecordMutation={updateEntity}
|
updateRecordMutation={updateEntity}
|
||||||
/>
|
/>
|
||||||
<RecordIndexRemoveSortingModal recordIndexId={recordTableId} />
|
<RecordIndexRemoveSortingModal />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import { useSetRecordIndexEntityCount } from '@/object-record/record-index/hooks
|
|||||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||||
import { viewFieldAggregateOperationState } from '@/object-record/record-table/record-table-footer/states/viewFieldAggregateOperationState';
|
import { viewFieldAggregateOperationState } from '@/object-record/record-table/record-table-footer/states/viewFieldAggregateOperationState';
|
||||||
import { convertAggregateOperationToExtendedAggregateOperation } from '@/object-record/utils/convertAggregateOperationToExtendedAggregateOperation';
|
import { convertAggregateOperationToExtendedAggregateOperation } from '@/object-record/utils/convertAggregateOperationToExtendedAggregateOperation';
|
||||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
|
||||||
import { ViewField } from '@/views/types/ViewField';
|
import { ViewField } from '@/views/types/ViewField';
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
@ -48,10 +48,9 @@ export const RecordIndexTableContainerEffect = () => {
|
|||||||
|
|
||||||
const handleToggleColumnSort = useHandleToggleColumnSort({
|
const handleToggleColumnSort = useHandleToggleColumnSort({
|
||||||
objectNameSingular,
|
objectNameSingular,
|
||||||
viewBarId,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const { currentViewWithSavedFiltersAndSorts } = useGetCurrentView();
|
const { currentView } = useGetCurrentViewOnly();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setOnToggleColumnFilter(
|
setOnToggleColumnFilter(
|
||||||
@ -115,13 +114,10 @@ export const RecordIndexTableContainerEffect = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
currentViewWithSavedFiltersAndSorts?.viewFields.forEach((viewField) => {
|
currentView?.viewFields.forEach((viewField) => {
|
||||||
setViewFieldAggregateOperation(viewField);
|
setViewFieldAggregateOperation(viewField);
|
||||||
});
|
});
|
||||||
}, [
|
}, [currentView, setViewFieldAggregateOperation]);
|
||||||
currentViewWithSavedFiltersAndSorts?.viewFields,
|
|
||||||
setViewFieldAggregateOperation,
|
|
||||||
]);
|
|
||||||
|
|
||||||
return <></>;
|
return <></>;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,10 +5,9 @@ import { currentRecordFiltersComponentState } from '@/object-record/record-filte
|
|||||||
import { computeViewRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeViewRecordGqlOperationFilter';
|
import { computeViewRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeViewRecordGqlOperationFilter';
|
||||||
import { useCurrentRecordGroupDefinition } from '@/object-record/record-group/hooks/useCurrentRecordGroupDefinition';
|
import { useCurrentRecordGroupDefinition } from '@/object-record/record-group/hooks/useCurrentRecordGroupDefinition';
|
||||||
import { useRecordGroupFilter } from '@/object-record/record-group/hooks/useRecordGroupFilter';
|
import { useRecordGroupFilter } from '@/object-record/record-group/hooks/useRecordGroupFilter';
|
||||||
|
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
|
||||||
import { tableViewFilterGroupsComponentState } from '@/object-record/record-table/states/tableViewFilterGroupsComponentState';
|
import { tableViewFilterGroupsComponentState } from '@/object-record/record-table/states/tableViewFilterGroupsComponentState';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
|
||||||
import { mapViewSortsToSorts } from '@/views/utils/mapViewSortsToSorts';
|
|
||||||
|
|
||||||
export const useFindManyRecordIndexTableParams = (
|
export const useFindManyRecordIndexTableParams = (
|
||||||
objectNameSingular: string,
|
objectNameSingular: string,
|
||||||
@ -29,12 +28,9 @@ export const useFindManyRecordIndexTableParams = (
|
|||||||
recordTableId,
|
recordTableId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { currentViewWithCombinedFiltersAndSorts } =
|
const currentRecordSorts = useRecoilComponentValueV2(
|
||||||
useGetCurrentView(recordTableId);
|
currentRecordSortsComponentState,
|
||||||
|
);
|
||||||
const viewSorts = currentViewWithCombinedFiltersAndSorts?.viewSorts ?? [];
|
|
||||||
|
|
||||||
const sorts = mapViewSortsToSorts(viewSorts);
|
|
||||||
|
|
||||||
const currentRecordFilters = useRecoilComponentValueV2(
|
const currentRecordFilters = useRecoilComponentValueV2(
|
||||||
currentRecordFiltersComponentState,
|
currentRecordFiltersComponentState,
|
||||||
@ -49,7 +45,7 @@ export const useFindManyRecordIndexTableParams = (
|
|||||||
tableViewFilterGroups,
|
tableViewFilterGroups,
|
||||||
);
|
);
|
||||||
|
|
||||||
const orderBy = turnSortsIntoOrderBy(objectMetadataItem, sorts);
|
const orderBy = turnSortsIntoOrderBy(objectMetadataItem, currentRecordSorts);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
objectNameSingular,
|
objectNameSingular,
|
||||||
|
|||||||
@ -9,14 +9,14 @@ import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldM
|
|||||||
|
|
||||||
import { useSelectFilterUsedInDropdown } from '@/object-record/object-filter-dropdown/hooks/useSelectFilterUsedInDropdown';
|
import { useSelectFilterUsedInDropdown } from '@/object-record/object-filter-dropdown/hooks/useSelectFilterUsedInDropdown';
|
||||||
import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter';
|
import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter';
|
||||||
|
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||||
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||||
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
|
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
|
||||||
import { useSetActiveDropdownFocusIdAndMemorizePrevious } from '@/ui/layout/dropdown/hooks/useSetFocusedDropdownIdAndMemorizePrevious';
|
import { useSetActiveDropdownFocusIdAndMemorizePrevious } from '@/ui/layout/dropdown/hooks/useSetFocusedDropdownIdAndMemorizePrevious';
|
||||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||||
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
||||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
|
||||||
import { useUpsertCombinedViewFilters } from '@/views/hooks/useUpsertCombinedViewFilters';
|
|
||||||
import { useRecoilCallback, useRecoilValue } from 'recoil';
|
import { useRecoilCallback, useRecoilValue } from 'recoil';
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
|
|
||||||
@ -36,7 +36,6 @@ export const useHandleToggleColumnFilter = ({
|
|||||||
const { columnDefinitions } =
|
const { columnDefinitions } =
|
||||||
useColumnDefinitionsFromFieldMetadata(objectMetadataItem);
|
useColumnDefinitionsFromFieldMetadata(objectMetadataItem);
|
||||||
|
|
||||||
const { upsertCombinedViewFilter } = useUpsertCombinedViewFilters(viewBarId);
|
|
||||||
const { upsertRecordFilter } = useUpsertRecordFilter();
|
const { upsertRecordFilter } = useUpsertRecordFilter();
|
||||||
|
|
||||||
const { setActiveDropdownFocusIdAndMemorizePrevious } =
|
const { setActiveDropdownFocusIdAndMemorizePrevious } =
|
||||||
@ -70,11 +69,13 @@ export const useHandleToggleColumnFilter = ({
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView();
|
|
||||||
|
|
||||||
const { selectFilterUsedInDropdown } =
|
const { selectFilterUsedInDropdown } =
|
||||||
useSelectFilterUsedInDropdown(viewBarId);
|
useSelectFilterUsedInDropdown(viewBarId);
|
||||||
|
|
||||||
|
const currentRecordFilters = useRecoilComponentValueV2(
|
||||||
|
currentRecordFiltersComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
const handleToggleColumnFilter = useCallback(
|
const handleToggleColumnFilter = useCallback(
|
||||||
async (fieldMetadataId: string) => {
|
async (fieldMetadataId: string) => {
|
||||||
const correspondingColumnDefinition = columnDefinitions.find(
|
const correspondingColumnDefinition = columnDefinitions.find(
|
||||||
@ -86,12 +87,11 @@ export const useHandleToggleColumnFilter = ({
|
|||||||
|
|
||||||
const newFilterId = v4();
|
const newFilterId = v4();
|
||||||
|
|
||||||
const existingViewFilter =
|
const existingRecordFilter = currentRecordFilters.find(
|
||||||
currentViewWithCombinedFiltersAndSorts?.viewFilters.find(
|
(recordFilter) => recordFilter.fieldMetadataId === fieldMetadataId,
|
||||||
(viewFilter) => viewFilter.fieldMetadataId === fieldMetadataId,
|
);
|
||||||
);
|
|
||||||
|
|
||||||
if (!existingViewFilter) {
|
if (!isDefined(existingRecordFilter)) {
|
||||||
const fieldMetadataItem = availableFieldMetadataItemsForFilter.find(
|
const fieldMetadataItem = availableFieldMetadataItemsForFilter.find(
|
||||||
(fieldMetadataItemToFind) =>
|
(fieldMetadataItemToFind) =>
|
||||||
fieldMetadataItemToFind.id === fieldMetadataId,
|
fieldMetadataItemToFind.id === fieldMetadataId,
|
||||||
@ -121,19 +121,16 @@ export const useHandleToggleColumnFilter = ({
|
|||||||
|
|
||||||
upsertRecordFilter(newFilter);
|
upsertRecordFilter(newFilter);
|
||||||
|
|
||||||
await upsertCombinedViewFilter(newFilter);
|
|
||||||
|
|
||||||
selectFilterUsedInDropdown({ fieldMetadataItemId: fieldMetadataId });
|
selectFilterUsedInDropdown({ fieldMetadataItemId: fieldMetadataId });
|
||||||
}
|
}
|
||||||
|
|
||||||
openDropdown(existingViewFilter?.id ?? newFilterId);
|
openDropdown(existingRecordFilter?.id ?? newFilterId);
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
openDropdown,
|
openDropdown,
|
||||||
columnDefinitions,
|
columnDefinitions,
|
||||||
upsertCombinedViewFilter,
|
|
||||||
selectFilterUsedInDropdown,
|
selectFilterUsedInDropdown,
|
||||||
currentViewWithCombinedFiltersAndSorts,
|
currentRecordFilters,
|
||||||
availableFieldMetadataItemsForFilter,
|
availableFieldMetadataItemsForFilter,
|
||||||
upsertRecordFilter,
|
upsertRecordFilter,
|
||||||
],
|
],
|
||||||
|
|||||||
@ -4,17 +4,14 @@ import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/u
|
|||||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
import { useUpsertRecordSort } from '@/object-record/record-sort/hooks/useUpsertRecordSort';
|
import { useUpsertRecordSort } from '@/object-record/record-sort/hooks/useUpsertRecordSort';
|
||||||
import { RecordSort } from '@/object-record/record-sort/types/RecordSort';
|
import { RecordSort } from '@/object-record/record-sort/types/RecordSort';
|
||||||
import { useUpsertCombinedViewSorts } from '@/views/hooks/useUpsertCombinedViewSorts';
|
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
type UseHandleToggleColumnSortProps = {
|
type UseHandleToggleColumnSortProps = {
|
||||||
objectNameSingular: string;
|
objectNameSingular: string;
|
||||||
viewBarId: string;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useHandleToggleColumnSort = ({
|
export const useHandleToggleColumnSort = ({
|
||||||
viewBarId,
|
|
||||||
objectNameSingular,
|
objectNameSingular,
|
||||||
}: UseHandleToggleColumnSortProps) => {
|
}: UseHandleToggleColumnSortProps) => {
|
||||||
const { objectMetadataItem } = useObjectMetadataItem({
|
const { objectMetadataItem } = useObjectMetadataItem({
|
||||||
@ -24,8 +21,6 @@ export const useHandleToggleColumnSort = ({
|
|||||||
const { columnDefinitions } =
|
const { columnDefinitions } =
|
||||||
useColumnDefinitionsFromFieldMetadata(objectMetadataItem);
|
useColumnDefinitionsFromFieldMetadata(objectMetadataItem);
|
||||||
|
|
||||||
const { upsertCombinedViewSort } = useUpsertCombinedViewSorts(viewBarId);
|
|
||||||
|
|
||||||
const { upsertRecordSort } = useUpsertRecordSort();
|
const { upsertRecordSort } = useUpsertRecordSort();
|
||||||
|
|
||||||
const handleToggleColumnSort = useCallback(
|
const handleToggleColumnSort = useCallback(
|
||||||
@ -44,10 +39,8 @@ export const useHandleToggleColumnSort = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
upsertRecordSort(newSort);
|
upsertRecordSort(newSort);
|
||||||
|
|
||||||
await upsertCombinedViewSort(newSort);
|
|
||||||
},
|
},
|
||||||
[columnDefinitions, upsertCombinedViewSort, upsertRecordSort],
|
[columnDefinitions, upsertRecordSort],
|
||||||
);
|
);
|
||||||
|
|
||||||
return handleToggleColumnSort;
|
return handleToggleColumnSort;
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUp
|
|||||||
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||||
import { isSoftDeleteFilterActiveComponentState } from '@/object-record/record-table/states/isSoftDeleteFilterActiveComponentState';
|
import { isSoftDeleteFilterActiveComponentState } from '@/object-record/record-table/states/isSoftDeleteFilterActiveComponentState';
|
||||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||||
import { useUpsertCombinedViewFilters } from '@/views/hooks/useUpsertCombinedViewFilters';
|
|
||||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
@ -29,8 +29,6 @@ export const useHandleToggleTrashColumnFilter = ({
|
|||||||
const { columnDefinitions } =
|
const { columnDefinitions } =
|
||||||
useColumnDefinitionsFromFieldMetadata(objectMetadataItem);
|
useColumnDefinitionsFromFieldMetadata(objectMetadataItem);
|
||||||
|
|
||||||
const { upsertCombinedViewFilter } = useUpsertCombinedViewFilters(viewBarId);
|
|
||||||
|
|
||||||
const isSoftDeleteFilterActiveComponentRecoilState =
|
const isSoftDeleteFilterActiveComponentRecoilState =
|
||||||
useRecoilComponentCallbackStateV2(
|
useRecoilComponentCallbackStateV2(
|
||||||
isSoftDeleteFilterActiveComponentState,
|
isSoftDeleteFilterActiveComponentState,
|
||||||
@ -68,13 +66,7 @@ export const useHandleToggleTrashColumnFilter = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
upsertRecordFilter(newFilter);
|
upsertRecordFilter(newFilter);
|
||||||
upsertCombinedViewFilter(newFilter);
|
}, [columnDefinitions, objectMetadataItem, upsertRecordFilter]);
|
||||||
}, [
|
|
||||||
columnDefinitions,
|
|
||||||
objectMetadataItem,
|
|
||||||
upsertCombinedViewFilter,
|
|
||||||
upsertRecordFilter,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const toggleSoftDeleteFilterState = useRecoilCallback(
|
const toggleSoftDeleteFilterState = useRecoilCallback(
|
||||||
({ set }) =>
|
({ set }) =>
|
||||||
|
|||||||
@ -8,16 +8,13 @@ import { useRecordTableContextOrThrow } from '@/object-record/record-table/conte
|
|||||||
import { RecordTableEmptyStateDisplay } from '@/object-record/record-table/empty-state/components/RecordTableEmptyStateDisplay';
|
import { RecordTableEmptyStateDisplay } from '@/object-record/record-table/empty-state/components/RecordTableEmptyStateDisplay';
|
||||||
import { tableFiltersComponentState } from '@/object-record/record-table/states/tableFiltersComponentState';
|
import { tableFiltersComponentState } from '@/object-record/record-table/states/tableFiltersComponentState';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useDeleteCombinedViewFilters } from '@/views/hooks/useDeleteCombinedViewFilters';
|
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
|
|
||||||
export const RecordTableEmptyStateSoftDelete = () => {
|
export const RecordTableEmptyStateSoftDelete = () => {
|
||||||
const { objectMetadataItem, objectNameSingular, recordTableId } =
|
const { objectMetadataItem, objectNameSingular, recordTableId } =
|
||||||
useRecordTableContextOrThrow();
|
useRecordTableContextOrThrow();
|
||||||
|
|
||||||
const { deleteCombinedViewFilter } =
|
|
||||||
useDeleteCombinedViewFilters(recordTableId);
|
|
||||||
|
|
||||||
const tableFilters = useRecoilComponentValueV2(
|
const tableFilters = useRecoilComponentValueV2(
|
||||||
tableFiltersComponentState,
|
tableFiltersComponentState,
|
||||||
recordTableId,
|
recordTableId,
|
||||||
@ -40,7 +37,6 @@ export const RecordTableEmptyStateSoftDelete = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
removeRecordFilter(deletedFilter.fieldMetadataId);
|
removeRecordFilter(deletedFilter.fieldMetadataId);
|
||||||
deleteCombinedViewFilter(deletedFilter.id);
|
|
||||||
|
|
||||||
toggleSoftDeleteFilterState(false);
|
toggleSoftDeleteFilterState(false);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import { useAggregateRecords } from '@/object-record/hooks/useAggregateRecords';
|
import { useAggregateRecords } from '@/object-record/hooks/useAggregateRecords';
|
||||||
import { computeAggregateValueAndLabel } from '@/object-record/record-board/record-board-column/utils/computeAggregateValueAndLabel';
|
import { computeAggregateValueAndLabel } from '@/object-record/record-board/record-board-column/utils/computeAggregateValueAndLabel';
|
||||||
import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies';
|
import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies';
|
||||||
|
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||||
import { computeViewRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeViewRecordGqlOperationFilter';
|
import { computeViewRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeViewRecordGqlOperationFilter';
|
||||||
import { useRecordGroupFilter } from '@/object-record/record-group/hooks/useRecordGroupFilter';
|
import { useRecordGroupFilter } from '@/object-record/record-group/hooks/useRecordGroupFilter';
|
||||||
import { recordIndexFiltersState } from '@/object-record/record-index/states/recordIndexFiltersState';
|
|
||||||
import { recordIndexViewFilterGroupsState } from '@/object-record/record-index/states/recordIndexViewFilterGroupsState';
|
import { recordIndexViewFilterGroupsState } from '@/object-record/record-index/states/recordIndexViewFilterGroupsState';
|
||||||
import { AGGREGATE_OPERATIONS } from '@/object-record/record-table/constants/AggregateOperations';
|
import { AGGREGATE_OPERATIONS } from '@/object-record/record-table/constants/AggregateOperations';
|
||||||
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||||
@ -11,6 +11,7 @@ import { RecordTableColumnAggregateFooterCellContext } from '@/object-record/rec
|
|||||||
import { viewFieldAggregateOperationState } from '@/object-record/record-table/record-table-footer/states/viewFieldAggregateOperationState';
|
import { viewFieldAggregateOperationState } from '@/object-record/record-table/record-table-footer/states/viewFieldAggregateOperationState';
|
||||||
import { ExtendedAggregateOperations } from '@/object-record/record-table/types/ExtendedAggregateOperations';
|
import { ExtendedAggregateOperations } from '@/object-record/record-table/types/ExtendedAggregateOperations';
|
||||||
import { convertAggregateOperationToExtendedAggregateOperation } from '@/object-record/utils/convertAggregateOperationToExtendedAggregateOperation';
|
import { convertAggregateOperationToExtendedAggregateOperation } from '@/object-record/utils/convertAggregateOperationToExtendedAggregateOperation';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { UserContext } from '@/users/contexts/UserContext';
|
import { UserContext } from '@/users/contexts/UserContext';
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
@ -26,13 +27,15 @@ export const useAggregateRecordsForRecordTableColumnFooter = (
|
|||||||
recordIndexViewFilterGroupsState,
|
recordIndexViewFilterGroupsState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const recordIndexFilters = useRecoilValue(recordIndexFiltersState);
|
const currentRecordFilters = useRecoilComponentValueV2(
|
||||||
|
currentRecordFiltersComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
const { filterValueDependencies } = useFilterValueDependencies();
|
const { filterValueDependencies } = useFilterValueDependencies();
|
||||||
|
|
||||||
const requestFilters = computeViewRecordGqlOperationFilter(
|
const requestFilters = computeViewRecordGqlOperationFilter(
|
||||||
filterValueDependencies,
|
filterValueDependencies,
|
||||||
recordIndexFilters,
|
currentRecordFilters,
|
||||||
objectMetadataItem.fields,
|
objectMetadataItem.fields,
|
||||||
recordIndexViewFilterGroups,
|
recordIndexViewFilterGroups,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { viewFieldAggregateOperationState } from '@/object-record/record-table/r
|
|||||||
import { ExtendedAggregateOperations } from '@/object-record/record-table/types/ExtendedAggregateOperations';
|
import { ExtendedAggregateOperations } from '@/object-record/record-table/types/ExtendedAggregateOperations';
|
||||||
import { convertExtendedAggregateOperationToAggregateOperation } from '@/object-record/utils/convertExtendedAggregateOperationToAggregateOperation';
|
import { convertExtendedAggregateOperationToAggregateOperation } from '@/object-record/utils/convertExtendedAggregateOperationToAggregateOperation';
|
||||||
import { usePersistViewFieldRecords } from '@/views/hooks/internal/usePersistViewFieldRecords';
|
import { usePersistViewFieldRecords } from '@/views/hooks/internal/usePersistViewFieldRecords';
|
||||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
@ -11,12 +11,11 @@ export const useViewFieldAggregateOperation = () => {
|
|||||||
const { fieldMetadataId } = useContext(
|
const { fieldMetadataId } = useContext(
|
||||||
RecordTableColumnAggregateFooterDropdownContext,
|
RecordTableColumnAggregateFooterDropdownContext,
|
||||||
);
|
);
|
||||||
const { currentViewWithSavedFiltersAndSorts } = useGetCurrentView();
|
const { currentView } = useGetCurrentViewOnly();
|
||||||
|
|
||||||
const currentViewField =
|
const currentViewField = currentView?.viewFields?.find(
|
||||||
currentViewWithSavedFiltersAndSorts?.viewFields?.find(
|
(viewField) => viewField.fieldMetadataId === fieldMetadataId,
|
||||||
(viewField) => viewField.fieldMetadataId === fieldMetadataId,
|
);
|
||||||
);
|
|
||||||
const { updateViewFieldRecords } = usePersistViewFieldRecords();
|
const { updateViewFieldRecords } = usePersistViewFieldRecords();
|
||||||
const updateViewFieldAggregateOperation = (
|
const updateViewFieldAggregateOperation = (
|
||||||
aggregateOperation: ExtendedAggregateOperations | null,
|
aggregateOperation: ExtendedAggregateOperations | null,
|
||||||
|
|||||||
@ -4,29 +4,35 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
|||||||
|
|
||||||
import { AdvancedFilterRootLevelViewFilterGroup } from '@/object-record/advanced-filter/components/AdvancedFilterRootLevelViewFilterGroup';
|
import { AdvancedFilterRootLevelViewFilterGroup } from '@/object-record/advanced-filter/components/AdvancedFilterRootLevelViewFilterGroup';
|
||||||
import { useDeleteCombinedViewFilterGroup } from '@/object-record/advanced-filter/hooks/useDeleteCombinedViewFilterGroup';
|
import { useDeleteCombinedViewFilterGroup } from '@/object-record/advanced-filter/hooks/useDeleteCombinedViewFilterGroup';
|
||||||
|
import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter';
|
||||||
|
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { AdvancedFilterChip } from '@/views/components/AdvancedFilterChip';
|
import { AdvancedFilterChip } from '@/views/components/AdvancedFilterChip';
|
||||||
import { ADVANCED_FILTER_DROPDOWN_ID } from '@/views/constants/AdvancedFilterDropdownId';
|
import { ADVANCED_FILTER_DROPDOWN_ID } from '@/views/constants/AdvancedFilterDropdownId';
|
||||||
import { useDeleteCombinedViewFilters } from '@/views/hooks/useDeleteCombinedViewFilters';
|
|
||||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
|
|
||||||
export const AdvancedFilterDropdownButton = () => {
|
export const AdvancedFilterDropdownButton = () => {
|
||||||
const { deleteCombinedViewFilter } = useDeleteCombinedViewFilters();
|
|
||||||
const { deleteCombinedViewFilterGroup } = useDeleteCombinedViewFilterGroup();
|
const { deleteCombinedViewFilterGroup } = useDeleteCombinedViewFilterGroup();
|
||||||
|
|
||||||
const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView();
|
const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView();
|
||||||
|
|
||||||
const advancedViewFilterIds =
|
const currentRecordFilters = useRecoilComponentValueV2(
|
||||||
currentViewWithCombinedFiltersAndSorts?.viewFilters
|
currentRecordFiltersComponentState,
|
||||||
.filter((viewFilter) => isDefined(viewFilter.viewFilterGroupId))
|
);
|
||||||
.map((viewFilter) => viewFilter.id);
|
|
||||||
|
const advancedRecordFilterIds = currentRecordFilters
|
||||||
|
.filter((recordFilter) => isDefined(recordFilter.viewFilterGroupId))
|
||||||
|
.map((recordFilter) => recordFilter.id);
|
||||||
|
|
||||||
|
const { removeRecordFilter } = useRemoveRecordFilter();
|
||||||
|
|
||||||
const handleDropdownClickOutside = useCallback(() => {}, []);
|
const handleDropdownClickOutside = useCallback(() => {}, []);
|
||||||
|
|
||||||
const handleDropdownClose = () => {};
|
const handleDropdownClose = () => {};
|
||||||
|
|
||||||
const removeAdvancedFilter = useCallback(async () => {
|
const removeAdvancedFilter = useCallback(async () => {
|
||||||
if (!advancedViewFilterIds) {
|
if (!advancedRecordFilterIds) {
|
||||||
throw new Error('No advanced view filters to remove');
|
throw new Error('No advanced view filters to remove');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,12 +45,12 @@ export const AdvancedFilterDropdownButton = () => {
|
|||||||
await deleteCombinedViewFilterGroup(viewFilterGroupId);
|
await deleteCombinedViewFilterGroup(viewFilterGroupId);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const viewFilterId of advancedViewFilterIds) {
|
for (const recordFilterId of advancedRecordFilterIds) {
|
||||||
await deleteCombinedViewFilter(viewFilterId);
|
removeRecordFilter(recordFilterId);
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
advancedViewFilterIds,
|
advancedRecordFilterIds,
|
||||||
deleteCombinedViewFilter,
|
removeRecordFilter,
|
||||||
deleteCombinedViewFilterGroup,
|
deleteCombinedViewFilterGroup,
|
||||||
currentViewWithCombinedFiltersAndSorts?.viewFilterGroups,
|
currentViewWithCombinedFiltersAndSorts?.viewFilterGroups,
|
||||||
]);
|
]);
|
||||||
@ -64,7 +70,7 @@ export const AdvancedFilterDropdownButton = () => {
|
|||||||
clickableComponent={
|
clickableComponent={
|
||||||
<AdvancedFilterChip
|
<AdvancedFilterChip
|
||||||
onRemove={removeAdvancedFilter}
|
onRemove={removeAdvancedFilter}
|
||||||
advancedFilterCount={advancedViewFilterIds?.length}
|
advancedFilterCount={advancedRecordFilterIds?.length}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
dropdownComponents={
|
dropdownComponents={
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import { ObjectFilterOperandSelectAndInput } from '@/object-record/object-filter
|
|||||||
import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter';
|
import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter';
|
||||||
import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand';
|
import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand';
|
||||||
import { EditableFilterDropdownButtonEffect } from '@/views/components/EditableFilterDropdownButtonEffect';
|
import { EditableFilterDropdownButtonEffect } from '@/views/components/EditableFilterDropdownButtonEffect';
|
||||||
import { useDeleteCombinedViewFilters } from '@/views/hooks/useDeleteCombinedViewFilters';
|
|
||||||
|
|
||||||
type EditableFilterDropdownButtonProps = {
|
type EditableFilterDropdownButtonProps = {
|
||||||
viewFilterDropdownId: string;
|
viewFilterDropdownId: string;
|
||||||
@ -25,19 +24,16 @@ export const EditableFilterDropdownButton = ({
|
|||||||
}: EditableFilterDropdownButtonProps) => {
|
}: EditableFilterDropdownButtonProps) => {
|
||||||
const { closeDropdown } = useDropdown(viewFilterDropdownId);
|
const { closeDropdown } = useDropdown(viewFilterDropdownId);
|
||||||
|
|
||||||
const { deleteCombinedViewFilter } = useDeleteCombinedViewFilters();
|
|
||||||
|
|
||||||
const { removeRecordFilter } = useRemoveRecordFilter();
|
const { removeRecordFilter } = useRemoveRecordFilter();
|
||||||
|
|
||||||
const handleRemove = () => {
|
const handleRemove = () => {
|
||||||
closeDropdown();
|
closeDropdown();
|
||||||
|
|
||||||
deleteCombinedViewFilter(viewFilter.id);
|
|
||||||
removeRecordFilter(viewFilter.fieldMetadataId);
|
removeRecordFilter(viewFilter.fieldMetadataId);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDropdownClickOutside = useCallback(() => {
|
const handleDropdownClickOutside = useCallback(() => {
|
||||||
const { id: fieldId, value, operand, fieldMetadataId } = viewFilter;
|
const { value, operand, fieldMetadataId } = viewFilter;
|
||||||
if (
|
if (
|
||||||
!value &&
|
!value &&
|
||||||
![
|
![
|
||||||
@ -49,9 +45,8 @@ export const EditableFilterDropdownButton = ({
|
|||||||
].includes(operand)
|
].includes(operand)
|
||||||
) {
|
) {
|
||||||
removeRecordFilter(fieldMetadataId);
|
removeRecordFilter(fieldMetadataId);
|
||||||
deleteCombinedViewFilter(fieldId);
|
|
||||||
}
|
}
|
||||||
}, [viewFilter, deleteCombinedViewFilter, removeRecordFilter]);
|
}, [viewFilter, removeRecordFilter]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -5,24 +5,17 @@ import { useRemoveRecordSort } from '@/object-record/record-sort/hooks/useRemove
|
|||||||
import { useUpsertRecordSort } from '@/object-record/record-sort/hooks/useUpsertRecordSort';
|
import { useUpsertRecordSort } from '@/object-record/record-sort/hooks/useUpsertRecordSort';
|
||||||
import { RecordSort } from '@/object-record/record-sort/types/RecordSort';
|
import { RecordSort } from '@/object-record/record-sort/types/RecordSort';
|
||||||
import { SortOrFilterChip } from '@/views/components/SortOrFilterChip';
|
import { SortOrFilterChip } from '@/views/components/SortOrFilterChip';
|
||||||
import { useDeleteCombinedViewSorts } from '@/views/hooks/useDeleteCombinedViewSorts';
|
|
||||||
import { useUpsertCombinedViewSorts } from '@/views/hooks/useUpsertCombinedViewSorts';
|
|
||||||
|
|
||||||
type EditableSortChipProps = {
|
type EditableSortChipProps = {
|
||||||
recordSort: RecordSort;
|
recordSort: RecordSort;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const EditableSortChip = ({ recordSort }: EditableSortChipProps) => {
|
export const EditableSortChip = ({ recordSort }: EditableSortChipProps) => {
|
||||||
const { deleteCombinedViewSort } = useDeleteCombinedViewSorts();
|
|
||||||
|
|
||||||
const { removeRecordSort } = useRemoveRecordSort();
|
const { removeRecordSort } = useRemoveRecordSort();
|
||||||
|
|
||||||
const { upsertCombinedViewSort } = useUpsertCombinedViewSorts();
|
|
||||||
|
|
||||||
const { upsertRecordSort } = useUpsertRecordSort();
|
const { upsertRecordSort } = useUpsertRecordSort();
|
||||||
|
|
||||||
const handleRemoveClick = () => {
|
const handleRemoveClick = () => {
|
||||||
deleteCombinedViewSort(recordSort.fieldMetadataId);
|
|
||||||
removeRecordSort(recordSort.fieldMetadataId);
|
removeRecordSort(recordSort.fieldMetadataId);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -36,7 +29,6 @@ export const EditableSortChip = ({ recordSort }: EditableSortChipProps) => {
|
|||||||
direction: recordSort.direction === 'asc' ? 'desc' : 'asc',
|
direction: recordSort.direction === 'asc' ? 'desc' : 'asc',
|
||||||
};
|
};
|
||||||
|
|
||||||
upsertCombinedViewSort(newSort);
|
|
||||||
upsertRecordSort(newSort);
|
upsertRecordSort(newSort);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,26 +1,13 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
|
||||||
import { useSetRecoilComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentFamilyStateV2';
|
|
||||||
import { useViewFromQueryParams } from '@/views/hooks/internal/useViewFromQueryParams';
|
import { useViewFromQueryParams } from '@/views/hooks/internal/useViewFromQueryParams';
|
||||||
import { useApplyViewFiltersToCurrentRecordFilters } from '@/views/hooks/useApplyViewFiltersToCurrentRecordFilters';
|
import { useApplyViewFiltersToCurrentRecordFilters } from '@/views/hooks/useApplyViewFiltersToCurrentRecordFilters';
|
||||||
import { useResetUnsavedViewStates } from '@/views/hooks/useResetUnsavedViewStates';
|
import { useResetUnsavedViewStates } from '@/views/hooks/useResetUnsavedViewStates';
|
||||||
import { unsavedToUpsertViewFiltersComponentFamilyState } from '@/views/states/unsavedToUpsertViewFiltersComponentFamilyState';
|
|
||||||
|
|
||||||
export const QueryParamsFiltersEffect = () => {
|
export const QueryParamsFiltersEffect = () => {
|
||||||
const { hasFiltersQueryParams, getFiltersFromQueryParams, viewIdQueryParam } =
|
const { hasFiltersQueryParams, getFiltersFromQueryParams } =
|
||||||
useViewFromQueryParams();
|
useViewFromQueryParams();
|
||||||
|
|
||||||
const currentViewId = useRecoilComponentValueV2(
|
|
||||||
contextStoreCurrentViewIdComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const setUnsavedViewFilter = useSetRecoilComponentFamilyStateV2(
|
|
||||||
unsavedToUpsertViewFiltersComponentFamilyState,
|
|
||||||
{ viewId: viewIdQueryParam ?? currentViewId },
|
|
||||||
);
|
|
||||||
|
|
||||||
const { resetUnsavedViewStates } = useResetUnsavedViewStates();
|
const { resetUnsavedViewStates } = useResetUnsavedViewStates();
|
||||||
|
|
||||||
const { applyViewFiltersToCurrentRecordFilters } =
|
const { applyViewFiltersToCurrentRecordFilters } =
|
||||||
@ -34,7 +21,6 @@ export const QueryParamsFiltersEffect = () => {
|
|||||||
getFiltersFromQueryParams().then((filtersFromParams) => {
|
getFiltersFromQueryParams().then((filtersFromParams) => {
|
||||||
if (Array.isArray(filtersFromParams)) {
|
if (Array.isArray(filtersFromParams)) {
|
||||||
applyViewFiltersToCurrentRecordFilters(filtersFromParams);
|
applyViewFiltersToCurrentRecordFilters(filtersFromParams);
|
||||||
setUnsavedViewFilter(filtersFromParams);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, [
|
}, [
|
||||||
@ -42,7 +28,6 @@ export const QueryParamsFiltersEffect = () => {
|
|||||||
getFiltersFromQueryParams,
|
getFiltersFromQueryParams,
|
||||||
hasFiltersQueryParams,
|
hasFiltersQueryParams,
|
||||||
resetUnsavedViewStates,
|
resetUnsavedViewStates,
|
||||||
setUnsavedViewFilter,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return <></>;
|
return <></>;
|
||||||
|
|||||||
@ -4,15 +4,12 @@ import { useFieldMetadataItemById } from '@/object-metadata/hooks/useFieldMetada
|
|||||||
import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter';
|
import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter';
|
||||||
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||||
import { SortOrFilterChip } from '@/views/components/SortOrFilterChip';
|
import { SortOrFilterChip } from '@/views/components/SortOrFilterChip';
|
||||||
import { useDeleteCombinedViewFilters } from '@/views/hooks/useDeleteCombinedViewFilters';
|
|
||||||
|
|
||||||
type RecordFilterChipProps = {
|
type RecordFilterChipProps = {
|
||||||
recordFilter: RecordFilter;
|
recordFilter: RecordFilter;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RecordFilterChip = ({ recordFilter }: RecordFilterChipProps) => {
|
export const RecordFilterChip = ({ recordFilter }: RecordFilterChipProps) => {
|
||||||
const { deleteCombinedViewFilter } = useDeleteCombinedViewFilters();
|
|
||||||
|
|
||||||
const { fieldMetadataItem } = useFieldMetadataItemById(
|
const { fieldMetadataItem } = useFieldMetadataItemById(
|
||||||
recordFilter.fieldMetadataId,
|
recordFilter.fieldMetadataId,
|
||||||
);
|
);
|
||||||
@ -24,7 +21,6 @@ export const RecordFilterChip = ({ recordFilter }: RecordFilterChipProps) => {
|
|||||||
const FieldMetadataItemIcon = getIcon(fieldMetadataItem.icon);
|
const FieldMetadataItemIcon = getIcon(fieldMetadataItem.icon);
|
||||||
|
|
||||||
const handleRemoveClick = () => {
|
const handleRemoveClick = () => {
|
||||||
deleteCombinedViewFilter(recordFilter.id);
|
|
||||||
removeRecordFilter(recordFilter.fieldMetadataId);
|
removeRecordFilter(recordFilter.fieldMetadataId);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
|||||||
import { isSoftDeleteFilterActiveComponentState } from '@/object-record/record-table/states/isSoftDeleteFilterActiveComponentState';
|
import { isSoftDeleteFilterActiveComponentState } from '@/object-record/record-table/states/isSoftDeleteFilterActiveComponentState';
|
||||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||||
import { SortOrFilterChip } from '@/views/components/SortOrFilterChip';
|
import { SortOrFilterChip } from '@/views/components/SortOrFilterChip';
|
||||||
import { useDeleteCombinedViewFilters } from '@/views/hooks/useDeleteCombinedViewFilters';
|
|
||||||
|
|
||||||
type SoftDeleteFilterChipProps = {
|
type SoftDeleteFilterChipProps = {
|
||||||
recordFilter: RecordFilter;
|
recordFilter: RecordFilter;
|
||||||
@ -16,8 +15,6 @@ export const SoftDeleteFilterChip = ({
|
|||||||
recordFilter,
|
recordFilter,
|
||||||
viewBarId,
|
viewBarId,
|
||||||
}: SoftDeleteFilterChipProps) => {
|
}: SoftDeleteFilterChipProps) => {
|
||||||
const { deleteCombinedViewFilter } = useDeleteCombinedViewFilters();
|
|
||||||
|
|
||||||
const setIsSoftDeleteFilterActive = useSetRecoilComponentStateV2(
|
const setIsSoftDeleteFilterActive = useSetRecoilComponentStateV2(
|
||||||
isSoftDeleteFilterActiveComponentState,
|
isSoftDeleteFilterActiveComponentState,
|
||||||
viewBarId,
|
viewBarId,
|
||||||
@ -28,7 +25,6 @@ export const SoftDeleteFilterChip = ({
|
|||||||
const { getIcon } = useIcons();
|
const { getIcon } = useIcons();
|
||||||
|
|
||||||
const handleRemoveClick = () => {
|
const handleRemoveClick = () => {
|
||||||
deleteCombinedViewFilter(recordFilter.id);
|
|
||||||
removeRecordFilter(recordFilter.fieldMetadataId);
|
removeRecordFilter(recordFilter.fieldMetadataId);
|
||||||
|
|
||||||
setIsSoftDeleteFilterActive(false);
|
setIsSoftDeleteFilterActive(false);
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import { QueryParamsFiltersEffect } from '@/views/components/QueryParamsFiltersE
|
|||||||
import { ViewBarFilterEffect } from '@/views/components/ViewBarFilterEffect';
|
import { ViewBarFilterEffect } from '@/views/components/ViewBarFilterEffect';
|
||||||
import { ViewBarPageTitle } from '@/views/components/ViewBarPageTitle';
|
import { ViewBarPageTitle } from '@/views/components/ViewBarPageTitle';
|
||||||
import { ViewBarSkeletonLoader } from '@/views/components/ViewBarSkeletonLoader';
|
import { ViewBarSkeletonLoader } from '@/views/components/ViewBarSkeletonLoader';
|
||||||
import { ViewBarSortEffect } from '@/views/components/ViewBarSortEffect';
|
|
||||||
import { ViewPickerDropdown } from '@/views/view-picker/components/ViewPickerDropdown';
|
import { ViewPickerDropdown } from '@/views/view-picker/components/ViewPickerDropdown';
|
||||||
|
|
||||||
import { ViewsHotkeyScope } from '../types/ViewsHotkeyScope';
|
import { ViewsHotkeyScope } from '../types/ViewsHotkeyScope';
|
||||||
@ -51,9 +50,7 @@ export const ViewBar = ({
|
|||||||
<ViewBarRecordFilterEffect />
|
<ViewBarRecordFilterEffect />
|
||||||
<ViewBarRecordSortEffect />
|
<ViewBarRecordSortEffect />
|
||||||
<ViewBarFilterEffect filterDropdownId={filterDropdownId} />
|
<ViewBarFilterEffect filterDropdownId={filterDropdownId} />
|
||||||
<ViewBarSortEffect />
|
|
||||||
<QueryParamsFiltersEffect />
|
<QueryParamsFiltersEffect />
|
||||||
|
|
||||||
<ViewBarPageTitle viewBarId={viewBarId} />
|
<ViewBarPageTitle viewBarId={viewBarId} />
|
||||||
<TopBar
|
<TopBar
|
||||||
className={className}
|
className={className}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-sta
|
|||||||
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
||||||
import { objectFilterDropdownSelectedOptionValuesComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedOptionValuesComponentState';
|
import { objectFilterDropdownSelectedOptionValuesComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedOptionValuesComponentState';
|
||||||
import { objectFilterDropdownSelectedRecordIdsComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsComponentState';
|
import { objectFilterDropdownSelectedRecordIdsComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSelectedRecordIdsComponentState';
|
||||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||||
import { jsonRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/jsonRelationFilterValueSchema';
|
import { jsonRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/jsonRelationFilterValueSchema';
|
||||||
import { simpleRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/simpleRelationFilterValueSchema';
|
import { simpleRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/simpleRelationFilterValueSchema';
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
@ -19,8 +19,6 @@ type ViewBarFilterEffectProps = {
|
|||||||
export const ViewBarFilterEffect = ({
|
export const ViewBarFilterEffect = ({
|
||||||
filterDropdownId,
|
filterDropdownId,
|
||||||
}: ViewBarFilterEffectProps) => {
|
}: ViewBarFilterEffectProps) => {
|
||||||
const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView();
|
|
||||||
|
|
||||||
const fieldMetadataItemUsedInDropdown = useRecoilComponentValueV2(
|
const fieldMetadataItemUsedInDropdown = useRecoilComponentValueV2(
|
||||||
fieldMetadataItemUsedInDropdownComponentSelector,
|
fieldMetadataItemUsedInDropdownComponentSelector,
|
||||||
filterDropdownId,
|
filterDropdownId,
|
||||||
@ -37,46 +35,48 @@ export const ViewBarFilterEffect = ({
|
|||||||
filterDropdownId,
|
filterDropdownId,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const currentRecordFilters = useRecoilComponentValueV2(
|
||||||
|
currentRecordFiltersComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (fieldMetadataItemUsedInDropdown?.type === 'RELATION') {
|
if (fieldMetadataItemUsedInDropdown?.type === 'RELATION') {
|
||||||
const viewFilterUsedInDropdown =
|
const recordFilterUsedInDropdown = currentRecordFilters.find(
|
||||||
currentViewWithCombinedFiltersAndSorts?.viewFilters.find(
|
(filter) =>
|
||||||
(filter) =>
|
filter.fieldMetadataId === fieldMetadataItemUsedInDropdown?.id,
|
||||||
filter.fieldMetadataId === fieldMetadataItemUsedInDropdown?.id,
|
);
|
||||||
);
|
|
||||||
|
|
||||||
const { selectedRecordIds } = jsonRelationFilterValueSchema
|
const { selectedRecordIds } = jsonRelationFilterValueSchema
|
||||||
.catch({
|
.catch({
|
||||||
isCurrentWorkspaceMemberSelected: false,
|
isCurrentWorkspaceMemberSelected: false,
|
||||||
selectedRecordIds: simpleRelationFilterValueSchema.parse(
|
selectedRecordIds: simpleRelationFilterValueSchema.parse(
|
||||||
viewFilterUsedInDropdown?.value,
|
recordFilterUsedInDropdown?.value,
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
.parse(viewFilterUsedInDropdown?.value);
|
.parse(recordFilterUsedInDropdown?.value);
|
||||||
|
|
||||||
setObjectFilterDropdownSelectedRecordIds(selectedRecordIds);
|
setObjectFilterDropdownSelectedRecordIds(selectedRecordIds);
|
||||||
} else if (
|
} else if (
|
||||||
isDefined(fieldMetadataItemUsedInDropdown) &&
|
isDefined(fieldMetadataItemUsedInDropdown) &&
|
||||||
['SELECT', 'MULTI_SELECT'].includes(fieldMetadataItemUsedInDropdown.type)
|
['SELECT', 'MULTI_SELECT'].includes(fieldMetadataItemUsedInDropdown.type)
|
||||||
) {
|
) {
|
||||||
const viewFilterUsedInDropdown =
|
const recordFilterUsedInDropdown = currentRecordFilters.find(
|
||||||
currentViewWithCombinedFiltersAndSorts?.viewFilters.find(
|
(filter) =>
|
||||||
(filter) =>
|
filter.fieldMetadataId === fieldMetadataItemUsedInDropdown?.id,
|
||||||
filter.fieldMetadataId === fieldMetadataItemUsedInDropdown?.id,
|
);
|
||||||
);
|
|
||||||
|
|
||||||
const viewFilterSelectedRecords = isNonEmptyString(
|
const recordFilterSelectedRecords = isNonEmptyString(
|
||||||
viewFilterUsedInDropdown?.value,
|
recordFilterUsedInDropdown?.value,
|
||||||
)
|
)
|
||||||
? JSON.parse(viewFilterUsedInDropdown.value)
|
? JSON.parse(recordFilterUsedInDropdown.value)
|
||||||
: [];
|
: [];
|
||||||
setObjectFilterDropdownSelectedOptionValues(viewFilterSelectedRecords);
|
setObjectFilterDropdownSelectedOptionValues(recordFilterSelectedRecords);
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
fieldMetadataItemUsedInDropdown,
|
fieldMetadataItemUsedInDropdown,
|
||||||
setObjectFilterDropdownSelectedRecordIds,
|
setObjectFilterDropdownSelectedRecordIds,
|
||||||
setObjectFilterDropdownSelectedOptionValues,
|
setObjectFilterDropdownSelectedOptionValues,
|
||||||
currentViewWithCombinedFiltersAndSorts,
|
currentRecordFilters,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return <></>;
|
return <></>;
|
||||||
|
|||||||
@ -1,29 +0,0 @@
|
|||||||
import { useEffect } from 'react';
|
|
||||||
|
|
||||||
import { onSortSelectComponentState } from '@/object-record/object-sort-dropdown/states/onSortSelectScopedState';
|
|
||||||
import { useUpsertRecordSort } from '@/object-record/record-sort/hooks/useUpsertRecordSort';
|
|
||||||
import { RecordSort } from '@/object-record/record-sort/types/RecordSort';
|
|
||||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
|
||||||
import { useUpsertCombinedViewSorts } from '@/views/hooks/useUpsertCombinedViewSorts';
|
|
||||||
import { isDefined } from 'twenty-shared';
|
|
||||||
|
|
||||||
export const ViewBarSortEffect = () => {
|
|
||||||
const { upsertCombinedViewSort } = useUpsertCombinedViewSorts();
|
|
||||||
|
|
||||||
const { upsertRecordSort } = useUpsertRecordSort();
|
|
||||||
|
|
||||||
const setOnSortSelect = useSetRecoilComponentStateV2(
|
|
||||||
onSortSelectComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setOnSortSelect(() => (sort: RecordSort | null) => {
|
|
||||||
if (isDefined(sort)) {
|
|
||||||
upsertCombinedViewSort(sort);
|
|
||||||
upsertRecordSort(sort);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, [setOnSortSelect, upsertCombinedViewSort, upsertRecordSort]);
|
|
||||||
|
|
||||||
return <></>;
|
|
||||||
};
|
|
||||||
@ -2,23 +2,26 @@ import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/
|
|||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
|
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
|
||||||
import { useLazyFindManyRecords } from '@/object-record/hooks/useLazyFindManyRecords';
|
import { useLazyFindManyRecords } from '@/object-record/hooks/useLazyFindManyRecords';
|
||||||
|
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||||
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
||||||
|
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
|
||||||
import { prefetchViewFromViewIdFamilySelector } from '@/prefetch/states/selector/prefetchViewFromViewIdFamilySelector';
|
import { prefetchViewFromViewIdFamilySelector } from '@/prefetch/states/selector/prefetchViewFromViewIdFamilySelector';
|
||||||
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
||||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { usePersistViewFieldRecords } from '@/views/hooks/internal/usePersistViewFieldRecords';
|
import { usePersistViewFieldRecords } from '@/views/hooks/internal/usePersistViewFieldRecords';
|
||||||
import { usePersistViewFilterGroupRecords } from '@/views/hooks/internal/usePersistViewFilterGroupRecords';
|
import { usePersistViewFilterGroupRecords } from '@/views/hooks/internal/usePersistViewFilterGroupRecords';
|
||||||
import { usePersistViewFilterRecords } from '@/views/hooks/internal/usePersistViewFilterRecords';
|
import { usePersistViewFilterRecords } from '@/views/hooks/internal/usePersistViewFilterRecords';
|
||||||
import { usePersistViewGroupRecords } from '@/views/hooks/internal/usePersistViewGroupRecords';
|
import { usePersistViewGroupRecords } from '@/views/hooks/internal/usePersistViewGroupRecords';
|
||||||
import { usePersistViewSortRecords } from '@/views/hooks/internal/usePersistViewSortRecords';
|
import { usePersistViewSortRecords } from '@/views/hooks/internal/usePersistViewSortRecords';
|
||||||
import { useGetViewFilterGroupsCombined } from '@/views/hooks/useGetCombinedViewFilterGroups';
|
import { useGetViewFilterGroupsCombined } from '@/views/hooks/useGetCombinedViewFilterGroups';
|
||||||
import { useGetViewFiltersCombined } from '@/views/hooks/useGetCombinedViewFilters';
|
|
||||||
import { useGetViewSortsCombined } from '@/views/hooks/useGetCombinedViewSorts';
|
|
||||||
import { isPersistingViewFieldsState } from '@/views/states/isPersistingViewFieldsState';
|
import { isPersistingViewFieldsState } from '@/views/states/isPersistingViewFieldsState';
|
||||||
import { GraphQLView } from '@/views/types/GraphQLView';
|
import { GraphQLView } from '@/views/types/GraphQLView';
|
||||||
import { View } from '@/views/types/View';
|
import { View } from '@/views/types/View';
|
||||||
import { ViewGroup } from '@/views/types/ViewGroup';
|
import { ViewGroup } from '@/views/types/ViewGroup';
|
||||||
import { ViewType } from '@/views/types/ViewType';
|
import { ViewType } from '@/views/types/ViewType';
|
||||||
|
import { mapRecordFilterToViewFilter } from '@/views/utils/mapRecordFilterToViewFilter';
|
||||||
|
import { mapRecordSortToViewSort } from '@/views/utils/mapRecordSortToViewSort';
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
@ -36,9 +39,6 @@ export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => {
|
|||||||
|
|
||||||
const { createViewFieldRecords } = usePersistViewFieldRecords();
|
const { createViewFieldRecords } = usePersistViewFieldRecords();
|
||||||
|
|
||||||
const { getViewSortsCombined } = useGetViewSortsCombined(viewBarComponentId);
|
|
||||||
const { getViewFiltersCombined } =
|
|
||||||
useGetViewFiltersCombined(viewBarComponentId);
|
|
||||||
const { getViewFilterGroupsCombined } =
|
const { getViewFilterGroupsCombined } =
|
||||||
useGetViewFilterGroupsCombined(viewBarComponentId);
|
useGetViewFilterGroupsCombined(viewBarComponentId);
|
||||||
|
|
||||||
@ -57,6 +57,14 @@ export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => {
|
|||||||
fetchPolicy: 'network-only',
|
fetchPolicy: 'network-only',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const currentRecordSorts = useRecoilComponentValueV2(
|
||||||
|
currentRecordSortsComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const currentRecordFilters = useRecoilComponentValueV2(
|
||||||
|
currentRecordFiltersComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
const createViewFromCurrentView = useRecoilCallback(
|
const createViewFromCurrentView = useRecoilCallback(
|
||||||
({ snapshot, set }) =>
|
({ snapshot, set }) =>
|
||||||
async (
|
async (
|
||||||
@ -160,13 +168,16 @@ export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => {
|
|||||||
const sourceViewCombinedFilterGroups = getViewFilterGroupsCombined(
|
const sourceViewCombinedFilterGroups = getViewFilterGroupsCombined(
|
||||||
sourceView.id,
|
sourceView.id,
|
||||||
);
|
);
|
||||||
const sourceViewCombinedFilters = getViewFiltersCombined(
|
|
||||||
sourceView.id,
|
|
||||||
);
|
|
||||||
const sourceViewCombinedSorts = getViewSortsCombined(sourceView.id);
|
|
||||||
|
|
||||||
await createViewSortRecords(sourceViewCombinedSorts, newView);
|
const viewSortsToCreate = currentRecordSorts.map(
|
||||||
await createViewFilterRecords(sourceViewCombinedFilters, newView);
|
mapRecordSortToViewSort,
|
||||||
|
);
|
||||||
|
const viewFiltersToCreate = currentRecordFilters.map(
|
||||||
|
mapRecordFilterToViewFilter,
|
||||||
|
);
|
||||||
|
|
||||||
|
await createViewSortRecords(viewSortsToCreate, newView);
|
||||||
|
await createViewFilterRecords(viewFiltersToCreate, newView);
|
||||||
await createViewFilterGroupRecords(
|
await createViewFilterGroupRecords(
|
||||||
sourceViewCombinedFilterGroups,
|
sourceViewCombinedFilterGroups,
|
||||||
newView,
|
newView,
|
||||||
@ -182,13 +193,13 @@ export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => {
|
|||||||
createViewFieldRecords,
|
createViewFieldRecords,
|
||||||
findManyRecords,
|
findManyRecords,
|
||||||
objectMetadataItem.fields,
|
objectMetadataItem.fields,
|
||||||
createViewGroupRecords,
|
|
||||||
getViewFilterGroupsCombined,
|
getViewFilterGroupsCombined,
|
||||||
getViewFiltersCombined,
|
createViewGroupRecords,
|
||||||
getViewSortsCombined,
|
|
||||||
createViewSortRecords,
|
createViewSortRecords,
|
||||||
createViewFilterRecords,
|
createViewFilterRecords,
|
||||||
createViewFilterGroupRecords,
|
createViewFilterGroupRecords,
|
||||||
|
currentRecordFilters,
|
||||||
|
currentRecordSorts,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,101 +0,0 @@
|
|||||||
import { useRecoilCallback } from 'recoil';
|
|
||||||
|
|
||||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
|
||||||
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
|
||||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
|
||||||
import { useGetViewFromPrefetchState } from '@/views/hooks/useGetViewFromPrefetchState';
|
|
||||||
import { unsavedToDeleteViewFilterIdsComponentFamilyState } from '@/views/states/unsavedToDeleteViewFilterIdsComponentFamilyState';
|
|
||||||
import { unsavedToUpsertViewFiltersComponentFamilyState } from '@/views/states/unsavedToUpsertViewFiltersComponentFamilyState';
|
|
||||||
import { isDefined } from 'twenty-shared';
|
|
||||||
|
|
||||||
export const useDeleteCombinedViewFilters = (viewBarComponentId?: string) => {
|
|
||||||
const unsavedToUpsertViewFiltersCallbackState =
|
|
||||||
useRecoilComponentCallbackStateV2(
|
|
||||||
unsavedToUpsertViewFiltersComponentFamilyState,
|
|
||||||
viewBarComponentId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToDeleteViewFilterIdsCallbackState =
|
|
||||||
useRecoilComponentCallbackStateV2(
|
|
||||||
unsavedToDeleteViewFilterIdsComponentFamilyState,
|
|
||||||
viewBarComponentId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const currentViewIdCallbackState = useRecoilComponentCallbackStateV2(
|
|
||||||
contextStoreCurrentViewIdComponentState,
|
|
||||||
viewBarComponentId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const { getViewFromPrefetchState } = useGetViewFromPrefetchState();
|
|
||||||
|
|
||||||
const deleteCombinedViewFilter = useRecoilCallback(
|
|
||||||
({ snapshot, set }) =>
|
|
||||||
async (fieldId: string) => {
|
|
||||||
const currentViewId = getSnapshotValue(
|
|
||||||
snapshot,
|
|
||||||
currentViewIdCallbackState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToUpsertViewFilters = getSnapshotValue(
|
|
||||||
snapshot,
|
|
||||||
unsavedToUpsertViewFiltersCallbackState({ viewId: currentViewId }),
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToDeleteViewFilterIds = getSnapshotValue(
|
|
||||||
snapshot,
|
|
||||||
unsavedToDeleteViewFilterIdsCallbackState({ viewId: currentViewId }),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!currentViewId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentView = await getViewFromPrefetchState(currentViewId);
|
|
||||||
|
|
||||||
if (!currentView) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const matchingFilterInCurrentView = currentView.viewFilters.find(
|
|
||||||
(viewFilter) => viewFilter.id === fieldId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const matchingFilterInUnsavedFilters = unsavedToUpsertViewFilters.find(
|
|
||||||
(viewFilter) => viewFilter.id === fieldId,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isDefined(matchingFilterInUnsavedFilters)) {
|
|
||||||
set(
|
|
||||||
unsavedToUpsertViewFiltersCallbackState({ viewId: currentViewId }),
|
|
||||||
unsavedToUpsertViewFilters.filter(
|
|
||||||
(viewFilter) => viewFilter.id !== fieldId,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDefined(matchingFilterInCurrentView)) {
|
|
||||||
set(
|
|
||||||
unsavedToDeleteViewFilterIdsCallbackState({
|
|
||||||
viewId: currentViewId,
|
|
||||||
}),
|
|
||||||
[
|
|
||||||
...new Set([
|
|
||||||
...unsavedToDeleteViewFilterIds,
|
|
||||||
matchingFilterInCurrentView.id,
|
|
||||||
]),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[
|
|
||||||
currentViewIdCallbackState,
|
|
||||||
getViewFromPrefetchState,
|
|
||||||
unsavedToDeleteViewFilterIdsCallbackState,
|
|
||||||
unsavedToUpsertViewFiltersCallbackState,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
deleteCombinedViewFilter,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -1,99 +0,0 @@
|
|||||||
import { useRecoilCallback } from 'recoil';
|
|
||||||
|
|
||||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
|
||||||
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
|
||||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
|
||||||
import { useGetViewFromPrefetchState } from '@/views/hooks/useGetViewFromPrefetchState';
|
|
||||||
import { unsavedToDeleteViewSortIdsComponentFamilyState } from '@/views/states/unsavedToDeleteViewSortIdsComponentFamilyState';
|
|
||||||
import { unsavedToUpsertViewSortsComponentFamilyState } from '@/views/states/unsavedToUpsertViewSortsComponentFamilyState';
|
|
||||||
import { isDefined } from 'twenty-shared';
|
|
||||||
|
|
||||||
export const useDeleteCombinedViewSorts = (viewBarComponentId?: string) => {
|
|
||||||
const currentViewIdCallbackState = useRecoilComponentCallbackStateV2(
|
|
||||||
contextStoreCurrentViewIdComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToUpsertViewSortsCallbackState =
|
|
||||||
useRecoilComponentCallbackStateV2(
|
|
||||||
unsavedToUpsertViewSortsComponentFamilyState,
|
|
||||||
viewBarComponentId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToDeleteViewSortIdsCallbackState =
|
|
||||||
useRecoilComponentCallbackStateV2(
|
|
||||||
unsavedToDeleteViewSortIdsComponentFamilyState,
|
|
||||||
viewBarComponentId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const { getViewFromPrefetchState } = useGetViewFromPrefetchState();
|
|
||||||
|
|
||||||
const deleteCombinedViewSort = useRecoilCallback(
|
|
||||||
({ snapshot, set }) =>
|
|
||||||
async (fieldMetadataId: string) => {
|
|
||||||
const currentViewId = getSnapshotValue(
|
|
||||||
snapshot,
|
|
||||||
currentViewIdCallbackState,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!currentViewId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsavedToUpsertViewSorts = getSnapshotValue(
|
|
||||||
snapshot,
|
|
||||||
unsavedToUpsertViewSortsCallbackState({ viewId: currentViewId }),
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToDeleteViewSortIds = getSnapshotValue(
|
|
||||||
snapshot,
|
|
||||||
unsavedToDeleteViewSortIdsCallbackState({ viewId: currentViewId }),
|
|
||||||
);
|
|
||||||
|
|
||||||
const currentView = await getViewFromPrefetchState(currentViewId);
|
|
||||||
|
|
||||||
if (!currentView) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const matchingSortInCurrentView = currentView.viewSorts.find(
|
|
||||||
(viewSort) => viewSort.fieldMetadataId === fieldMetadataId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const matchingSortInUnsavedSorts = unsavedToUpsertViewSorts.find(
|
|
||||||
(viewSort) => viewSort.fieldMetadataId === fieldMetadataId,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isDefined(matchingSortInUnsavedSorts)) {
|
|
||||||
set(
|
|
||||||
unsavedToUpsertViewSortsCallbackState({ viewId: currentViewId }),
|
|
||||||
unsavedToUpsertViewSorts.filter(
|
|
||||||
(viewSort) => viewSort.fieldMetadataId !== fieldMetadataId,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDefined(matchingSortInCurrentView)) {
|
|
||||||
set(
|
|
||||||
unsavedToDeleteViewSortIdsCallbackState({ viewId: currentViewId }),
|
|
||||||
[
|
|
||||||
...new Set([
|
|
||||||
...unsavedToDeleteViewSortIds,
|
|
||||||
matchingSortInCurrentView.id,
|
|
||||||
]),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[
|
|
||||||
currentViewIdCallbackState,
|
|
||||||
getViewFromPrefetchState,
|
|
||||||
unsavedToDeleteViewSortIdsCallbackState,
|
|
||||||
unsavedToUpsertViewSortsCallbackState,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
deleteCombinedViewSort,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -1,68 +0,0 @@
|
|||||||
import { useRecoilCallback } from 'recoil';
|
|
||||||
|
|
||||||
import { prefetchViewFromViewIdFamilySelector } from '@/prefetch/states/selector/prefetchViewFromViewIdFamilySelector';
|
|
||||||
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
|
||||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
|
||||||
import { unsavedToDeleteViewFilterIdsComponentFamilyState } from '@/views/states/unsavedToDeleteViewFilterIdsComponentFamilyState';
|
|
||||||
import { unsavedToUpsertViewFiltersComponentFamilyState } from '@/views/states/unsavedToUpsertViewFiltersComponentFamilyState';
|
|
||||||
import { getCombinedViewFilters } from '@/views/utils/getCombinedViewFilters';
|
|
||||||
import { isDefined } from 'twenty-shared';
|
|
||||||
|
|
||||||
export const useGetViewFiltersCombined = (viewBarComponentId?: string) => {
|
|
||||||
const unsavedToUpsertViewFiltersCallbackState =
|
|
||||||
useRecoilComponentCallbackStateV2(
|
|
||||||
unsavedToUpsertViewFiltersComponentFamilyState,
|
|
||||||
viewBarComponentId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToDeleteViewFilterIdsCallbackState =
|
|
||||||
useRecoilComponentCallbackStateV2(
|
|
||||||
unsavedToDeleteViewFilterIdsComponentFamilyState,
|
|
||||||
viewBarComponentId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const getViewFiltersCombined = useRecoilCallback(
|
|
||||||
({ snapshot }) =>
|
|
||||||
(viewId: string) => {
|
|
||||||
const view = snapshot
|
|
||||||
.getLoadable(
|
|
||||||
prefetchViewFromViewIdFamilySelector({
|
|
||||||
viewId,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.getValue();
|
|
||||||
|
|
||||||
if (!isDefined(view)) {
|
|
||||||
throw new Error(
|
|
||||||
`Cannot get view with id ${viewId}, because it cannot be found in client cache data.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsavedToUpsertViewFilters = getSnapshotValue(
|
|
||||||
snapshot,
|
|
||||||
unsavedToUpsertViewFiltersCallbackState({ viewId: view.id }),
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToDeleteViewFilterIds = getSnapshotValue(
|
|
||||||
snapshot,
|
|
||||||
unsavedToDeleteViewFilterIdsCallbackState({ viewId: view.id }),
|
|
||||||
);
|
|
||||||
|
|
||||||
const combinedViewFilters = getCombinedViewFilters(
|
|
||||||
view.viewFilters,
|
|
||||||
unsavedToUpsertViewFilters,
|
|
||||||
unsavedToDeleteViewFilterIds,
|
|
||||||
);
|
|
||||||
|
|
||||||
return combinedViewFilters;
|
|
||||||
},
|
|
||||||
[
|
|
||||||
unsavedToDeleteViewFilterIdsCallbackState,
|
|
||||||
unsavedToUpsertViewFiltersCallbackState,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
getViewFiltersCombined,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
import { useRecoilCallback } from 'recoil';
|
|
||||||
|
|
||||||
import { prefetchViewFromViewIdFamilySelector } from '@/prefetch/states/selector/prefetchViewFromViewIdFamilySelector';
|
|
||||||
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
|
||||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
|
||||||
import { unsavedToDeleteViewSortIdsComponentFamilyState } from '@/views/states/unsavedToDeleteViewSortIdsComponentFamilyState';
|
|
||||||
import { unsavedToUpsertViewSortsComponentFamilyState } from '@/views/states/unsavedToUpsertViewSortsComponentFamilyState';
|
|
||||||
import { getCombinedViewSorts } from '@/views/utils/getCombinedViewSorts';
|
|
||||||
import { isDefined } from 'twenty-shared';
|
|
||||||
|
|
||||||
// TODO: fix naming
|
|
||||||
export const useGetViewSortsCombined = (viewBarComponentId?: string) => {
|
|
||||||
const unsavedToUpsertViewSortsCallbackState =
|
|
||||||
useRecoilComponentCallbackStateV2(
|
|
||||||
unsavedToUpsertViewSortsComponentFamilyState,
|
|
||||||
viewBarComponentId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToDeleteViewSortIdsCallbackState =
|
|
||||||
useRecoilComponentCallbackStateV2(
|
|
||||||
unsavedToDeleteViewSortIdsComponentFamilyState,
|
|
||||||
viewBarComponentId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const getViewSortsCombined = useRecoilCallback(
|
|
||||||
({ snapshot }) =>
|
|
||||||
(viewId: string) => {
|
|
||||||
const view = snapshot
|
|
||||||
.getLoadable(
|
|
||||||
prefetchViewFromViewIdFamilySelector({
|
|
||||||
viewId,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.getValue();
|
|
||||||
|
|
||||||
if (!isDefined(view)) {
|
|
||||||
throw new Error(
|
|
||||||
`Cannot get view with id ${viewId}, because it cannot be found in client cache data.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsavedToUpsertViewSorts = getSnapshotValue(
|
|
||||||
snapshot,
|
|
||||||
unsavedToUpsertViewSortsCallbackState({ viewId: view.id }),
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToDeleteViewSortIds = getSnapshotValue(
|
|
||||||
snapshot,
|
|
||||||
unsavedToDeleteViewSortIdsCallbackState({ viewId: view.id }),
|
|
||||||
);
|
|
||||||
|
|
||||||
const combinedViewSorts = getCombinedViewSorts(
|
|
||||||
view.viewSorts,
|
|
||||||
unsavedToUpsertViewSorts,
|
|
||||||
unsavedToDeleteViewSortIds,
|
|
||||||
);
|
|
||||||
|
|
||||||
return combinedViewSorts;
|
|
||||||
},
|
|
||||||
[
|
|
||||||
unsavedToDeleteViewSortIdsCallbackState,
|
|
||||||
unsavedToUpsertViewSortsCallbackState,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
getViewSortsCombined,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -12,14 +12,8 @@ import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-sta
|
|||||||
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
||||||
import { isCurrentViewKeyIndexComponentState } from '@/views/states/isCurrentViewIndexComponentState';
|
import { isCurrentViewKeyIndexComponentState } from '@/views/states/isCurrentViewIndexComponentState';
|
||||||
import { unsavedToDeleteViewFilterGroupIdsComponentFamilyState } from '@/views/states/unsavedToDeleteViewFilterGroupIdsComponentFamilyState';
|
import { unsavedToDeleteViewFilterGroupIdsComponentFamilyState } from '@/views/states/unsavedToDeleteViewFilterGroupIdsComponentFamilyState';
|
||||||
import { unsavedToDeleteViewFilterIdsComponentFamilyState } from '@/views/states/unsavedToDeleteViewFilterIdsComponentFamilyState';
|
|
||||||
import { unsavedToDeleteViewSortIdsComponentFamilyState } from '@/views/states/unsavedToDeleteViewSortIdsComponentFamilyState';
|
|
||||||
import { unsavedToUpsertViewFilterGroupsComponentFamilyState } from '@/views/states/unsavedToUpsertViewFilterGroupsComponentFamilyState';
|
import { unsavedToUpsertViewFilterGroupsComponentFamilyState } from '@/views/states/unsavedToUpsertViewFilterGroupsComponentFamilyState';
|
||||||
import { unsavedToUpsertViewFiltersComponentFamilyState } from '@/views/states/unsavedToUpsertViewFiltersComponentFamilyState';
|
|
||||||
import { unsavedToUpsertViewSortsComponentFamilyState } from '@/views/states/unsavedToUpsertViewSortsComponentFamilyState';
|
|
||||||
import { getCombinedViewFilterGroups } from '@/views/utils/getCombinedViewFilterGroups';
|
import { getCombinedViewFilterGroups } from '@/views/utils/getCombinedViewFilterGroups';
|
||||||
import { getCombinedViewFilters } from '@/views/utils/getCombinedViewFilters';
|
|
||||||
import { getCombinedViewSorts } from '@/views/utils/getCombinedViewSorts';
|
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
|
|
||||||
@ -71,42 +65,18 @@ export const useGetCurrentView = (viewBarInstanceId?: string) => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const unsavedToUpsertViewFilters = useRecoilComponentFamilyValueV2(
|
|
||||||
unsavedToUpsertViewFiltersComponentFamilyState,
|
|
||||||
{ viewId },
|
|
||||||
instanceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToUpsertViewFilterGroups = useRecoilComponentFamilyValueV2(
|
const unsavedToUpsertViewFilterGroups = useRecoilComponentFamilyValueV2(
|
||||||
unsavedToUpsertViewFilterGroupsComponentFamilyState,
|
unsavedToUpsertViewFilterGroupsComponentFamilyState,
|
||||||
{ viewId },
|
{ viewId },
|
||||||
instanceId,
|
instanceId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const unsavedToUpsertViewSorts = useRecoilComponentFamilyValueV2(
|
|
||||||
unsavedToUpsertViewSortsComponentFamilyState,
|
|
||||||
{ viewId },
|
|
||||||
instanceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToDeleteViewFilterIds = useRecoilComponentFamilyValueV2(
|
|
||||||
unsavedToDeleteViewFilterIdsComponentFamilyState,
|
|
||||||
{ viewId },
|
|
||||||
instanceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToDeleteViewFilterGroupIds = useRecoilComponentFamilyValueV2(
|
const unsavedToDeleteViewFilterGroupIds = useRecoilComponentFamilyValueV2(
|
||||||
unsavedToDeleteViewFilterGroupIdsComponentFamilyState,
|
unsavedToDeleteViewFilterGroupIdsComponentFamilyState,
|
||||||
{ viewId },
|
{ viewId },
|
||||||
instanceId,
|
instanceId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const unsavedToDeleteViewSortIds = useRecoilComponentFamilyValueV2(
|
|
||||||
unsavedToDeleteViewSortIdsComponentFamilyState,
|
|
||||||
{ viewId },
|
|
||||||
instanceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!isDefined(currentView)) {
|
if (!isDefined(currentView)) {
|
||||||
return {
|
return {
|
||||||
instanceId,
|
instanceId,
|
||||||
@ -118,26 +88,15 @@ export const useGetCurrentView = (viewBarInstanceId?: string) => {
|
|||||||
|
|
||||||
const currentViewWithCombinedFiltersAndSorts = {
|
const currentViewWithCombinedFiltersAndSorts = {
|
||||||
...currentView,
|
...currentView,
|
||||||
viewFilters: getCombinedViewFilters(
|
|
||||||
currentView.viewFilters,
|
|
||||||
unsavedToUpsertViewFilters,
|
|
||||||
unsavedToDeleteViewFilterIds,
|
|
||||||
),
|
|
||||||
viewFilterGroups: getCombinedViewFilterGroups(
|
viewFilterGroups: getCombinedViewFilterGroups(
|
||||||
currentView.viewFilterGroups ?? [],
|
currentView.viewFilterGroups ?? [],
|
||||||
unsavedToUpsertViewFilterGroups,
|
unsavedToUpsertViewFilterGroups,
|
||||||
unsavedToDeleteViewFilterGroupIds,
|
unsavedToDeleteViewFilterGroupIds,
|
||||||
),
|
),
|
||||||
viewSorts: getCombinedViewSorts(
|
|
||||||
currentView.viewSorts,
|
|
||||||
unsavedToUpsertViewSorts,
|
|
||||||
unsavedToDeleteViewSortIds,
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
instanceId,
|
instanceId,
|
||||||
currentViewWithSavedFiltersAndSorts: currentView,
|
|
||||||
currentViewWithCombinedFiltersAndSorts,
|
currentViewWithCombinedFiltersAndSorts,
|
||||||
viewsOnCurrentObject: viewsOnCurrentObject ?? [],
|
viewsOnCurrentObject: viewsOnCurrentObject ?? [],
|
||||||
currentViewId,
|
currentViewId,
|
||||||
|
|||||||
@ -1,43 +1,15 @@
|
|||||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||||
import { unsavedToDeleteViewFilterGroupIdsComponentFamilyState } from '@/views/states/unsavedToDeleteViewFilterGroupIdsComponentFamilyState';
|
import { unsavedToDeleteViewFilterGroupIdsComponentFamilyState } from '@/views/states/unsavedToDeleteViewFilterGroupIdsComponentFamilyState';
|
||||||
import { unsavedToDeleteViewFilterIdsComponentFamilyState } from '@/views/states/unsavedToDeleteViewFilterIdsComponentFamilyState';
|
|
||||||
import { unsavedToDeleteViewSortIdsComponentFamilyState } from '@/views/states/unsavedToDeleteViewSortIdsComponentFamilyState';
|
|
||||||
import { unsavedToUpsertViewFilterGroupsComponentFamilyState } from '@/views/states/unsavedToUpsertViewFilterGroupsComponentFamilyState';
|
import { unsavedToUpsertViewFilterGroupsComponentFamilyState } from '@/views/states/unsavedToUpsertViewFilterGroupsComponentFamilyState';
|
||||||
import { unsavedToUpsertViewFiltersComponentFamilyState } from '@/views/states/unsavedToUpsertViewFiltersComponentFamilyState';
|
|
||||||
import { unsavedToUpsertViewSortsComponentFamilyState } from '@/views/states/unsavedToUpsertViewSortsComponentFamilyState';
|
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
export const useResetUnsavedViewStates = (viewBarInstanceId?: string) => {
|
export const useResetUnsavedViewStates = (viewBarInstanceId?: string) => {
|
||||||
const setUnsavedToDeleteViewFilterIdsCallbackState =
|
|
||||||
useRecoilComponentCallbackStateV2(
|
|
||||||
unsavedToDeleteViewFilterIdsComponentFamilyState,
|
|
||||||
viewBarInstanceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const setUnsavedToDeleteViewSortIdsCallbackState =
|
|
||||||
useRecoilComponentCallbackStateV2(
|
|
||||||
unsavedToDeleteViewSortIdsComponentFamilyState,
|
|
||||||
viewBarInstanceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToDeleteViewFilterGroupIdsCallbackState =
|
const unsavedToDeleteViewFilterGroupIdsCallbackState =
|
||||||
useRecoilComponentCallbackStateV2(
|
useRecoilComponentCallbackStateV2(
|
||||||
unsavedToDeleteViewFilterGroupIdsComponentFamilyState,
|
unsavedToDeleteViewFilterGroupIdsComponentFamilyState,
|
||||||
viewBarInstanceId,
|
viewBarInstanceId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const setUnsavedToUpsertViewFiltersCallbackState =
|
|
||||||
useRecoilComponentCallbackStateV2(
|
|
||||||
unsavedToUpsertViewFiltersComponentFamilyState,
|
|
||||||
viewBarInstanceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToUpsertViewSortsCallbackState =
|
|
||||||
useRecoilComponentCallbackStateV2(
|
|
||||||
unsavedToUpsertViewSortsComponentFamilyState,
|
|
||||||
viewBarInstanceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToUpsertViewFilterGroupsCallbackState =
|
const unsavedToUpsertViewFilterGroupsCallbackState =
|
||||||
useRecoilComponentCallbackStateV2(
|
useRecoilComponentCallbackStateV2(
|
||||||
unsavedToUpsertViewFilterGroupsComponentFamilyState,
|
unsavedToUpsertViewFilterGroupsComponentFamilyState,
|
||||||
@ -48,18 +20,10 @@ export const useResetUnsavedViewStates = (viewBarInstanceId?: string) => {
|
|||||||
({ set }) =>
|
({ set }) =>
|
||||||
(viewId: string) => {
|
(viewId: string) => {
|
||||||
set(unsavedToDeleteViewFilterGroupIdsCallbackState({ viewId }), []);
|
set(unsavedToDeleteViewFilterGroupIdsCallbackState({ viewId }), []);
|
||||||
set(setUnsavedToDeleteViewFilterIdsCallbackState({ viewId }), []);
|
|
||||||
set(setUnsavedToDeleteViewSortIdsCallbackState({ viewId }), []);
|
|
||||||
set(unsavedToUpsertViewFilterGroupsCallbackState({ viewId }), []);
|
set(unsavedToUpsertViewFilterGroupsCallbackState({ viewId }), []);
|
||||||
set(setUnsavedToUpsertViewFiltersCallbackState({ viewId }), []);
|
|
||||||
set(unsavedToUpsertViewSortsCallbackState({ viewId }), []);
|
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
unsavedToUpsertViewSortsCallbackState,
|
|
||||||
setUnsavedToUpsertViewFiltersCallbackState,
|
|
||||||
unsavedToUpsertViewFilterGroupsCallbackState,
|
unsavedToUpsertViewFilterGroupsCallbackState,
|
||||||
setUnsavedToDeleteViewSortIdsCallbackState,
|
|
||||||
setUnsavedToDeleteViewFilterIdsCallbackState,
|
|
||||||
unsavedToDeleteViewFilterGroupIdsCallbackState,
|
unsavedToDeleteViewFilterGroupIdsCallbackState,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,132 +0,0 @@
|
|||||||
import { useRecoilCallback } from 'recoil';
|
|
||||||
|
|
||||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
|
||||||
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
|
||||||
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
|
||||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
|
||||||
import { useGetViewFromPrefetchState } from '@/views/hooks/useGetViewFromPrefetchState';
|
|
||||||
import { unsavedToDeleteViewFilterIdsComponentFamilyState } from '@/views/states/unsavedToDeleteViewFilterIdsComponentFamilyState';
|
|
||||||
import { unsavedToUpsertViewFiltersComponentFamilyState } from '@/views/states/unsavedToUpsertViewFiltersComponentFamilyState';
|
|
||||||
import { ViewFilter } from '@/views/types/ViewFilter';
|
|
||||||
import { shouldReplaceFilter } from '@/views/utils/shouldReplaceFilter';
|
|
||||||
import { isDefined } from 'twenty-shared';
|
|
||||||
|
|
||||||
export const useUpsertCombinedViewFilters = (viewBarComponentId?: string) => {
|
|
||||||
const unsavedToUpsertViewFiltersCallbackState =
|
|
||||||
useRecoilComponentCallbackStateV2(
|
|
||||||
unsavedToUpsertViewFiltersComponentFamilyState,
|
|
||||||
viewBarComponentId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToDeleteViewFilterIdsCallbackState =
|
|
||||||
useRecoilComponentCallbackStateV2(
|
|
||||||
unsavedToDeleteViewFilterIdsComponentFamilyState,
|
|
||||||
viewBarComponentId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const currentViewIdCallbackState = useRecoilComponentCallbackStateV2(
|
|
||||||
contextStoreCurrentViewIdComponentState,
|
|
||||||
viewBarComponentId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const { getViewFromPrefetchState } = useGetViewFromPrefetchState();
|
|
||||||
|
|
||||||
const upsertCombinedViewFilter = useRecoilCallback(
|
|
||||||
({ snapshot, set }) =>
|
|
||||||
async (upsertedFilter: RecordFilter) => {
|
|
||||||
const currentViewId = getSnapshotValue(
|
|
||||||
snapshot,
|
|
||||||
currentViewIdCallbackState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToUpsertViewFilters = getSnapshotValue(
|
|
||||||
snapshot,
|
|
||||||
unsavedToUpsertViewFiltersCallbackState({ viewId: currentViewId }),
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToDeleteViewFilterIds = getSnapshotValue(
|
|
||||||
snapshot,
|
|
||||||
unsavedToDeleteViewFilterIdsCallbackState({ viewId: currentViewId }),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!currentViewId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentView = await getViewFromPrefetchState(currentViewId);
|
|
||||||
|
|
||||||
if (!currentView) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const matchingFilterInCurrentView = currentView.viewFilters.find(
|
|
||||||
(viewFilter) => shouldReplaceFilter(viewFilter, upsertedFilter),
|
|
||||||
);
|
|
||||||
|
|
||||||
const matchingFilterInUnsavedFilters = unsavedToUpsertViewFilters.find(
|
|
||||||
(viewFilter) => shouldReplaceFilter(viewFilter, upsertedFilter),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isDefined(matchingFilterInUnsavedFilters)) {
|
|
||||||
const updatedFilters = unsavedToUpsertViewFilters.map((viewFilter) =>
|
|
||||||
shouldReplaceFilter(viewFilter, matchingFilterInUnsavedFilters)
|
|
||||||
? { ...viewFilter, ...upsertedFilter, id: viewFilter.id }
|
|
||||||
: viewFilter,
|
|
||||||
);
|
|
||||||
|
|
||||||
set(
|
|
||||||
unsavedToUpsertViewFiltersCallbackState({ viewId: currentViewId }),
|
|
||||||
updatedFilters,
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDefined(matchingFilterInCurrentView)) {
|
|
||||||
set(
|
|
||||||
unsavedToUpsertViewFiltersCallbackState({ viewId: currentViewId }),
|
|
||||||
[
|
|
||||||
...unsavedToUpsertViewFilters,
|
|
||||||
{
|
|
||||||
...matchingFilterInCurrentView,
|
|
||||||
...upsertedFilter,
|
|
||||||
id: matchingFilterInCurrentView.id,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
);
|
|
||||||
set(
|
|
||||||
unsavedToDeleteViewFilterIdsCallbackState({
|
|
||||||
viewId: currentViewId,
|
|
||||||
}),
|
|
||||||
unsavedToDeleteViewFilterIds.filter(
|
|
||||||
(id) => id !== matchingFilterInCurrentView.id,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const newValue = [
|
|
||||||
...unsavedToUpsertViewFilters,
|
|
||||||
{
|
|
||||||
...upsertedFilter,
|
|
||||||
id: upsertedFilter.id,
|
|
||||||
__typename: 'ViewFilter',
|
|
||||||
} satisfies ViewFilter,
|
|
||||||
] satisfies ViewFilter[];
|
|
||||||
|
|
||||||
set(
|
|
||||||
unsavedToUpsertViewFiltersCallbackState({ viewId: currentViewId }),
|
|
||||||
newValue,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
[
|
|
||||||
currentViewIdCallbackState,
|
|
||||||
getViewFromPrefetchState,
|
|
||||||
unsavedToDeleteViewFilterIdsCallbackState,
|
|
||||||
unsavedToUpsertViewFiltersCallbackState,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
upsertCombinedViewFilter,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -1,120 +0,0 @@
|
|||||||
import { useRecoilCallback } from 'recoil';
|
|
||||||
|
|
||||||
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
|
|
||||||
import { RecordSort } from '@/object-record/record-sort/types/RecordSort';
|
|
||||||
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
|
||||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
|
||||||
import { useGetViewFromPrefetchState } from '@/views/hooks/useGetViewFromPrefetchState';
|
|
||||||
import { unsavedToDeleteViewSortIdsComponentFamilyState } from '@/views/states/unsavedToDeleteViewSortIdsComponentFamilyState';
|
|
||||||
import { unsavedToUpsertViewSortsComponentFamilyState } from '@/views/states/unsavedToUpsertViewSortsComponentFamilyState';
|
|
||||||
import { ViewSort } from '@/views/types/ViewSort';
|
|
||||||
import { isDefined } from 'twenty-shared';
|
|
||||||
|
|
||||||
export const useUpsertCombinedViewSorts = (viewBarComponentId?: string) => {
|
|
||||||
const currentViewIdCallbackState = useRecoilComponentCallbackStateV2(
|
|
||||||
contextStoreCurrentViewIdComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToUpsertViewSortsCallbackState =
|
|
||||||
useRecoilComponentCallbackStateV2(
|
|
||||||
unsavedToUpsertViewSortsComponentFamilyState,
|
|
||||||
viewBarComponentId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToDeleteViewSortIdsCallbackState =
|
|
||||||
useRecoilComponentCallbackStateV2(
|
|
||||||
unsavedToDeleteViewSortIdsComponentFamilyState,
|
|
||||||
viewBarComponentId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const { getViewFromPrefetchState } = useGetViewFromPrefetchState();
|
|
||||||
|
|
||||||
const upsertCombinedViewSort = useRecoilCallback(
|
|
||||||
({ snapshot, set }) =>
|
|
||||||
async (upsertedSort: RecordSort) => {
|
|
||||||
const currentViewId = getSnapshotValue(
|
|
||||||
snapshot,
|
|
||||||
currentViewIdCallbackState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToUpsertViewSorts = getSnapshotValue(
|
|
||||||
snapshot,
|
|
||||||
unsavedToUpsertViewSortsCallbackState({ viewId: currentViewId }),
|
|
||||||
);
|
|
||||||
|
|
||||||
const unsavedToDeleteViewSortIds = getSnapshotValue(
|
|
||||||
snapshot,
|
|
||||||
unsavedToDeleteViewSortIdsCallbackState({ viewId: currentViewId }),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!currentViewId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentView = await getViewFromPrefetchState(currentViewId);
|
|
||||||
|
|
||||||
if (!currentView) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const matchingSortInCurrentView = currentView.viewSorts.find(
|
|
||||||
(viewSort) =>
|
|
||||||
viewSort.fieldMetadataId === upsertedSort.fieldMetadataId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const matchingSortInUnsavedSorts = unsavedToUpsertViewSorts.find(
|
|
||||||
(viewSort) =>
|
|
||||||
viewSort.fieldMetadataId === upsertedSort.fieldMetadataId,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isDefined(matchingSortInUnsavedSorts)) {
|
|
||||||
const updatedSorts = unsavedToUpsertViewSorts.map((viewSort) =>
|
|
||||||
viewSort.id === matchingSortInUnsavedSorts.id
|
|
||||||
? { ...viewSort, ...upsertedSort }
|
|
||||||
: viewSort,
|
|
||||||
);
|
|
||||||
|
|
||||||
set(
|
|
||||||
unsavedToUpsertViewSortsCallbackState({ viewId: currentViewId }),
|
|
||||||
updatedSorts,
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDefined(matchingSortInCurrentView)) {
|
|
||||||
set(
|
|
||||||
unsavedToUpsertViewSortsCallbackState({ viewId: currentViewId }),
|
|
||||||
[
|
|
||||||
...unsavedToUpsertViewSorts,
|
|
||||||
{ ...matchingSortInCurrentView, ...upsertedSort },
|
|
||||||
],
|
|
||||||
);
|
|
||||||
set(
|
|
||||||
unsavedToDeleteViewSortIdsCallbackState({ viewId: currentViewId }),
|
|
||||||
unsavedToDeleteViewSortIds.filter(
|
|
||||||
(id) => id !== matchingSortInCurrentView.id,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
set(unsavedToUpsertViewSortsCallbackState({ viewId: currentViewId }), [
|
|
||||||
...unsavedToUpsertViewSorts,
|
|
||||||
{
|
|
||||||
...upsertedSort,
|
|
||||||
__typename: 'ViewSort',
|
|
||||||
} satisfies ViewSort,
|
|
||||||
]);
|
|
||||||
},
|
|
||||||
[
|
|
||||||
currentViewIdCallbackState,
|
|
||||||
getViewFromPrefetchState,
|
|
||||||
unsavedToDeleteViewSortIdsCallbackState,
|
|
||||||
unsavedToUpsertViewSortsCallbackState,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
upsertCombinedViewSort,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
import { createComponentFamilySelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentFamilySelectorV2';
|
|
||||||
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
|
||||||
import { unsavedToDeleteViewSortIdsComponentFamilyState } from '@/views/states/unsavedToDeleteViewSortIdsComponentFamilyState';
|
|
||||||
import { unsavedToUpsertViewSortsComponentFamilyState } from '@/views/states/unsavedToUpsertViewSortsComponentFamilyState';
|
|
||||||
|
|
||||||
export const areViewSortsDifferentFromRecordSortsSelector =
|
|
||||||
createComponentFamilySelectorV2<boolean, { viewId?: string }>({
|
|
||||||
key: 'areViewSortsDifferentFromRecordSortsSelector',
|
|
||||||
get:
|
|
||||||
({ familyKey, instanceId }) =>
|
|
||||||
({ get }) => {
|
|
||||||
return (
|
|
||||||
get(
|
|
||||||
unsavedToUpsertViewSortsComponentFamilyState.atomFamily({
|
|
||||||
familyKey,
|
|
||||||
instanceId,
|
|
||||||
}),
|
|
||||||
).length > 0 ||
|
|
||||||
get(
|
|
||||||
unsavedToDeleteViewSortIdsComponentFamilyState.atomFamily({
|
|
||||||
familyKey,
|
|
||||||
instanceId,
|
|
||||||
}),
|
|
||||||
).length > 0
|
|
||||||
);
|
|
||||||
},
|
|
||||||
componentInstanceContext: ViewComponentInstanceContext,
|
|
||||||
});
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
import { createComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentFamilyStateV2';
|
|
||||||
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
|
||||||
|
|
||||||
export const unsavedToDeleteViewFilterIdsComponentFamilyState =
|
|
||||||
createComponentFamilyStateV2<string[], { viewId?: string }>({
|
|
||||||
key: 'unsavedToDeleteViewFilterIdsComponentFamilyState',
|
|
||||||
defaultValue: [],
|
|
||||||
componentInstanceContext: ViewComponentInstanceContext,
|
|
||||||
});
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
import { createComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentFamilyStateV2';
|
|
||||||
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
|
||||||
|
|
||||||
export const unsavedToDeleteViewSortIdsComponentFamilyState =
|
|
||||||
createComponentFamilyStateV2<string[], { viewId?: string }>({
|
|
||||||
key: 'unsavedToDeleteViewSortIdsComponentFamilyState',
|
|
||||||
defaultValue: [],
|
|
||||||
componentInstanceContext: ViewComponentInstanceContext,
|
|
||||||
});
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
import { createComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentFamilyStateV2';
|
|
||||||
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
|
||||||
import { ViewFilter } from '@/views/types/ViewFilter';
|
|
||||||
|
|
||||||
export const unsavedToUpsertViewFiltersComponentFamilyState =
|
|
||||||
createComponentFamilyStateV2<ViewFilter[], { viewId?: string }>({
|
|
||||||
key: 'unsavedToUpsertViewFiltersComponentFamilyState',
|
|
||||||
defaultValue: [],
|
|
||||||
componentInstanceContext: ViewComponentInstanceContext,
|
|
||||||
});
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
import { createComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentFamilyStateV2';
|
|
||||||
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
|
||||||
import { ViewSort } from '../types/ViewSort';
|
|
||||||
|
|
||||||
export const unsavedToUpsertViewSortsComponentFamilyState =
|
|
||||||
createComponentFamilyStateV2<ViewSort[], { viewId?: string }>({
|
|
||||||
key: 'unsavedToUpsertViewSortsComponentFamilyState',
|
|
||||||
defaultValue: [],
|
|
||||||
componentInstanceContext: ViewComponentInstanceContext,
|
|
||||||
});
|
|
||||||
@ -1,112 +0,0 @@
|
|||||||
// Generate test for getCombinedViewFilters
|
|
||||||
|
|
||||||
import { ViewFilter } from '@/views/types/ViewFilter';
|
|
||||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
|
||||||
import { getCombinedViewFilters } from '../getCombinedViewFilters';
|
|
||||||
|
|
||||||
describe('getCombinedViewFilters', () => {
|
|
||||||
it('should return expected combined view filters when additional filters are present', () => {
|
|
||||||
const viewFilters: ViewFilter[] = [
|
|
||||||
{
|
|
||||||
__typename: 'ViewFilter',
|
|
||||||
id: 'id',
|
|
||||||
fieldMetadataId: '05731f68-6e7a-4903-8374-c0b6a9063482',
|
|
||||||
value: 'testValue',
|
|
||||||
displayValue: 'Test Display Value',
|
|
||||||
operand: ViewFilterOperand.Is,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const toUpsertViewFilters: ViewFilter[] = [
|
|
||||||
{
|
|
||||||
__typename: 'ViewFilter',
|
|
||||||
id: 'id',
|
|
||||||
fieldMetadataId: '05731f68-6e7a-4903-8374-c0b6a9063482',
|
|
||||||
value: 'testValue',
|
|
||||||
displayValue: 'Test Display Value',
|
|
||||||
operand: ViewFilterOperand.Is,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const toDeleteViewFilterIds: string[] = [];
|
|
||||||
|
|
||||||
expect(
|
|
||||||
getCombinedViewFilters(
|
|
||||||
viewFilters,
|
|
||||||
toUpsertViewFilters,
|
|
||||||
toDeleteViewFilterIds,
|
|
||||||
),
|
|
||||||
).toEqual([
|
|
||||||
{
|
|
||||||
__typename: 'ViewFilter',
|
|
||||||
id: 'id',
|
|
||||||
fieldMetadataId: '05731f68-6e7a-4903-8374-c0b6a9063482',
|
|
||||||
value: 'testValue',
|
|
||||||
displayValue: 'Test Display Value',
|
|
||||||
operand: ViewFilterOperand.Is,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return expected combined view filters when additional filters are not present', () => {
|
|
||||||
const viewFilters: ViewFilter[] = [
|
|
||||||
{
|
|
||||||
__typename: 'ViewFilter',
|
|
||||||
id: 'id',
|
|
||||||
fieldMetadataId: '05731f68-6e7a-4903-8374-c0b6a9063482',
|
|
||||||
value: 'testValue',
|
|
||||||
displayValue: 'Test Display Value',
|
|
||||||
operand: ViewFilterOperand.Is,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const toUpsertViewFilters: ViewFilter[] = [];
|
|
||||||
const toDeleteViewFilterIds: string[] = [];
|
|
||||||
|
|
||||||
expect(
|
|
||||||
getCombinedViewFilters(
|
|
||||||
viewFilters,
|
|
||||||
toUpsertViewFilters,
|
|
||||||
toDeleteViewFilterIds,
|
|
||||||
),
|
|
||||||
).toEqual([
|
|
||||||
{
|
|
||||||
__typename: 'ViewFilter',
|
|
||||||
id: 'id',
|
|
||||||
fieldMetadataId: '05731f68-6e7a-4903-8374-c0b6a9063482',
|
|
||||||
value: 'testValue',
|
|
||||||
displayValue: 'Test Display Value',
|
|
||||||
operand: ViewFilterOperand.Is,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return expected combined view filters when additional filters are present and some filters are to be deleted', () => {
|
|
||||||
const viewFilters: ViewFilter[] = [
|
|
||||||
{
|
|
||||||
__typename: 'ViewFilter',
|
|
||||||
id: 'id',
|
|
||||||
fieldMetadataId: '05731f68-6e7a-4903-8374-c0b6a9063482',
|
|
||||||
value: 'testValue',
|
|
||||||
displayValue: 'Test Display Value',
|
|
||||||
operand: ViewFilterOperand.Is,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const toUpsertViewFilters: ViewFilter[] = [
|
|
||||||
{
|
|
||||||
__typename: 'ViewFilter',
|
|
||||||
id: 'id',
|
|
||||||
fieldMetadataId: '05731f68-6e7a-4903-8374-c0b6a9063482',
|
|
||||||
value: 'testValue',
|
|
||||||
displayValue: 'Test Display Value',
|
|
||||||
operand: ViewFilterOperand.Is,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const toDeleteViewFilterIds: string[] = ['id'];
|
|
||||||
|
|
||||||
expect(
|
|
||||||
getCombinedViewFilters(
|
|
||||||
viewFilters,
|
|
||||||
toUpsertViewFilters,
|
|
||||||
toDeleteViewFilterIds,
|
|
||||||
),
|
|
||||||
).toEqual([]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
import { ViewFilter } from '@/views/types/ViewFilter';
|
|
||||||
|
|
||||||
export const getCombinedViewFilters = (
|
|
||||||
viewFilters: ViewFilter[],
|
|
||||||
toUpsertViewFilters: ViewFilter[],
|
|
||||||
toDeleteViewFilterIds: string[],
|
|
||||||
): ViewFilter[] => {
|
|
||||||
const toCreateViewFilters = toUpsertViewFilters.filter(
|
|
||||||
(toUpsertViewFilter) =>
|
|
||||||
!viewFilters.some(
|
|
||||||
(viewFilter) => viewFilter.id === toUpsertViewFilter.id,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
const toUpdateViewFilters = toUpsertViewFilters.filter((toUpsertViewFilter) =>
|
|
||||||
viewFilters.some((viewFilter) => viewFilter.id === toUpsertViewFilter.id),
|
|
||||||
);
|
|
||||||
|
|
||||||
const combinedViewFilters = viewFilters
|
|
||||||
.filter((viewFilter) => !toDeleteViewFilterIds.includes(viewFilter.id))
|
|
||||||
.map((viewFilter) => {
|
|
||||||
const toUpdateViewFilter = toUpdateViewFilters.find(
|
|
||||||
(toUpdateViewFilter) => toUpdateViewFilter.id === viewFilter.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
return toUpdateViewFilter ?? viewFilter;
|
|
||||||
})
|
|
||||||
.concat(toCreateViewFilters);
|
|
||||||
|
|
||||||
return Object.values(
|
|
||||||
combinedViewFilters.reduce((acc, obj) => ({ ...acc, [obj.id]: obj }), {}),
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
import { ViewSort } from '@/views/types/ViewSort';
|
|
||||||
|
|
||||||
export const getCombinedViewSorts = (
|
|
||||||
viewSort: ViewSort[],
|
|
||||||
toUpsertViewSorts: ViewSort[],
|
|
||||||
toDeleteViewSortIds: string[],
|
|
||||||
): ViewSort[] => {
|
|
||||||
const toCreateViewSorts = toUpsertViewSorts.filter(
|
|
||||||
(toUpsertViewSort) =>
|
|
||||||
!viewSort.some((viewSort) => viewSort.id === toUpsertViewSort.id),
|
|
||||||
);
|
|
||||||
|
|
||||||
const toUpdateViewSorts = toUpsertViewSorts.filter((toUpsertViewSort) =>
|
|
||||||
viewSort.some((viewSort) => viewSort.id === toUpsertViewSort.id),
|
|
||||||
);
|
|
||||||
|
|
||||||
const combinedViewSorts = viewSort
|
|
||||||
.filter((viewSort) => !toDeleteViewSortIds.includes(viewSort.id))
|
|
||||||
.map((viewSort) => {
|
|
||||||
const toUpdateViewSort = toUpdateViewSorts.find(
|
|
||||||
(toUpdateViewSort) => toUpdateViewSort.id === viewSort.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
return toUpdateViewSort ?? viewSort;
|
|
||||||
})
|
|
||||||
.concat(toCreateViewSorts);
|
|
||||||
|
|
||||||
return Object.values(
|
|
||||||
combinedViewSorts.reduce(
|
|
||||||
(acc, obj) => ({ ...acc, [obj.fieldMetadataId]: obj }),
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user