Skip to content

Commit 3f52c67

Browse files
eliasylonenad-eliaslucasbordeau
authored andcommitted
Current workspace member filter (twentyhq#8016) (twentyhq#9182)
New branch based on feedback in PR twentyhq#8950 and issue twentyhq#8016 --------- Co-authored-by: ad-elias <[email protected]> Co-authored-by: Lucas Bordeau <[email protected]>
1 parent 1f52a45 commit 3f52c67

29 files changed

+347
-155
lines changed

packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/hooks/useDeleteMultipleRecordsAction.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { DELETE_MAX_COUNT } from '@/object-record/constants/DeleteMaxCount';
1515
import { useDeleteManyRecords } from '@/object-record/hooks/useDeleteManyRecords';
1616
import { useLazyFetchAllRecords } from '@/object-record/hooks/useLazyFetchAllRecords';
1717
import { FilterOperand } from '@/object-record/object-filter-dropdown/types/FilterOperand';
18+
import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies';
1819
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
1920
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
2021
import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer';
@@ -52,10 +53,13 @@ export const useDeleteMultipleRecordsAction = ({
5253
contextStoreFiltersComponentState,
5354
);
5455

56+
const { filterValueDependencies } = useFilterValueDependencies();
57+
5558
const graphqlFilter = computeContextStoreFilters(
5659
contextStoreTargetedRecordsRule,
5760
contextStoreFilters,
5861
objectMetadataItem,
62+
filterValueDependencies,
5963
);
6064

6165
const deletedAtFieldMetadata = objectMetadataItem.fields.find(

packages/twenty-front/src/modules/context-store/hooks/useFindManyRecordsSelectedInContextStore.ts

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/s
44
import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters';
55
import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById';
66
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
7+
import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies';
78
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
89

910
export const useFindManyRecordsSelectedInContextStore = ({
@@ -30,10 +31,13 @@ export const useFindManyRecordsSelectedInContextStore = ({
3031
instanceId,
3132
);
3233

34+
const { filterValueDependencies } = useFilterValueDependencies();
35+
3336
const queryFilter = computeContextStoreFilters(
3437
contextStoreTargetedRecordsRule,
3538
contextStoreFilters,
3639
objectMetadataItem,
40+
filterValueDependencies,
3741
);
3842

3943
const { records, loading, totalCount } = useFindManyRecords({

packages/twenty-front/src/modules/context-store/utils/__tests__/computeContextStoreFilters.test.ts

+8
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
import { ContextStoreTargetedRecordsRule } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
22
import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters';
33
import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
4+
import { FilterValueDependencies } from '@/object-record/record-filter/types/FilterValueDependencies';
45
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
56
import { expect } from '@storybook/test';
67
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
8+
79
describe('computeContextStoreFilters', () => {
810
const personObjectMetadataItem = generatedMockObjectMetadataItems.find(
911
(item) => item.nameSingular === 'person',
1012
)!;
1113

14+
const mockFilterValueDependencies: FilterValueDependencies = {
15+
currentWorkspaceMemberId: '32219445-f587-4c40-b2b1-6d3205ed96da',
16+
};
17+
1218
it('should work for selection mode', () => {
1319
const contextStoreTargetedRecordsRule: ContextStoreTargetedRecordsRule = {
1420
mode: 'selection',
@@ -19,6 +25,7 @@ describe('computeContextStoreFilters', () => {
1925
contextStoreTargetedRecordsRule,
2026
[],
2127
personObjectMetadataItem,
28+
mockFilterValueDependencies,
2229
);
2330

2431
expect(filters).toEqual({
@@ -61,6 +68,7 @@ describe('computeContextStoreFilters', () => {
6168
contextStoreTargetedRecordsRule,
6269
contextStoreFilters,
6370
personObjectMetadataItem,
71+
mockFilterValueDependencies,
6472
);
6573

6674
expect(filters).toEqual({

packages/twenty-front/src/modules/context-store/utils/computeContextStoreFilters.ts

+4
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,22 @@ import { ContextStoreTargetedRecordsRule } from '@/context-store/states/contextS
22
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
33
import { RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter';
44
import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
5+
import { FilterValueDependencies } from '@/object-record/record-filter/types/FilterValueDependencies';
56
import { computeViewRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeViewRecordGqlOperationFilter';
67
import { makeAndFilterVariables } from '@/object-record/utils/makeAndFilterVariables';
78

89
export const computeContextStoreFilters = (
910
contextStoreTargetedRecordsRule: ContextStoreTargetedRecordsRule,
1011
contextStoreFilters: Filter[],
1112
objectMetadataItem: ObjectMetadataItem,
13+
filterValueDependencies: FilterValueDependencies,
1214
) => {
1315
let queryFilter: RecordGqlOperationFilter | undefined;
1416

1517
if (contextStoreTargetedRecordsRule.mode === 'exclusion') {
1618
queryFilter = makeAndFilterVariables([
1719
computeViewRecordGqlOperationFilter(
20+
filterValueDependencies,
1821
contextStoreFilters,
1922
objectMetadataItem?.fields ?? [],
2023
[],
@@ -39,6 +42,7 @@ export const computeContextStoreFilters = (
3942
},
4043
}
4144
: computeViewRecordGqlOperationFilter(
45+
filterValueDependencies,
4246
contextStoreFilters,
4347
objectMetadataItem?.fields ?? [],
4448
[],

packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownDateInput.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import { InternalDatePicker } from '@/ui/input/components/internal/date/componen
88
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
99
import { computeVariableDateViewFilterValue } from '@/views/view-filter-value/utils/computeVariableDateViewFilterValue';
1010
import {
11+
resolveDateViewFilterValue,
1112
VariableDateViewFilterValueDirection,
1213
VariableDateViewFilterValueUnit,
1314
} from '@/views/view-filter-value/utils/resolveDateViewFilterValue';
14-
import { resolveFilterValue } from '@/views/view-filter-value/utils/resolveFilterValue';
1515
import { useState } from 'react';
1616
import { isDefined } from 'twenty-ui';
1717
import { FieldMetadataType } from '~/generated-metadata/graphql';
@@ -37,7 +37,7 @@ export const ObjectFilterDropdownDateInput = () => {
3737
| undefined;
3838

3939
const initialFilterValue = selectedFilter
40-
? resolveFilterValue(selectedFilter)
40+
? resolveDateViewFilterValue(selectedFilter)
4141
: null;
4242
const [internalDate, setInternalDate] = useState<Date | null>(
4343
initialFilterValue instanceof Date ? initialFilterValue : null,
@@ -98,7 +98,7 @@ export const ObjectFilterDropdownDateInput = () => {
9898
selectedOperandInDropdown === ViewFilterOperand.IsRelative;
9999

100100
const resolvedValue = selectedFilter
101-
? resolveFilterValue(selectedFilter)
101+
? resolveDateViewFilterValue(selectedFilter)
102102
: null;
103103

104104
const relativeDate =
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { StyledMultipleSelectDropdownAvatarChip } from '@/object-record/select/components/StyledMultipleSelectDropdownAvatarChip';
2+
import { SelectableItem } from '@/object-record/select/types/SelectableItem';
3+
import styled from '@emotion/styled';
4+
import { MenuItemMultiSelectAvatar } from 'twenty-ui';
5+
6+
const StyledPinnedItemsContainer = styled.div`
7+
display: flex;
8+
flex-direction: column;
9+
padding: ${({ theme }) => theme.spacing(1)};
10+
`;
11+
12+
export const ObjectFilterDropdownRecordPinnedItems = (props: {
13+
selectableItems: SelectableItem[];
14+
onChange: (
15+
selectableItem: SelectableItem,
16+
isNewCheckedValue: boolean,
17+
) => void;
18+
}) => {
19+
return (
20+
<StyledPinnedItemsContainer>
21+
{props.selectableItems.map((selectableItem) => {
22+
return (
23+
<MenuItemMultiSelectAvatar
24+
key={selectableItem.id}
25+
selected={selectableItem.isSelected}
26+
onSelectChange={(newCheckedValue) => {
27+
props.onChange(selectableItem, newCheckedValue);
28+
}}
29+
avatar={
30+
<StyledMultipleSelectDropdownAvatarChip
31+
className="avatar-icon-container"
32+
name={selectableItem.name}
33+
avatarUrl={selectableItem.avatarUrl}
34+
LeftIcon={selectableItem.AvatarIcon}
35+
avatarType={selectableItem.avatarType}
36+
isIconInverted={selectableItem.isIconInverted}
37+
placeholderColorSeed={selectableItem.id}
38+
/>
39+
}
40+
/>
41+
);
42+
})}
43+
</StyledPinnedItemsContainer>
44+
);
45+
};

0 commit comments

Comments
 (0)