feat: added workspace member filter for actor fields (#16628)
Closes #16619 This PR adds support for filtering ACTOR fields by `Workspace Member` subfield, enabling users to filter records by who created them with a `Me` option. I replicated the same UX and code structure as the Relation field filter for consistency. Each filter selection triggers a server-side GraphQL call. But there is client-side filtering in `isRecordMatchingFilter.ts` which instantly filters already-loaded records while the server is fetching new results. I replicated this behaviour from how `FULL_NAME` and other composite fields handle filtering. UX decision that were taken by me (Let me know if changes are needed) : - The filter shows comma separated selected workspace member names until 3 members are selected. After that it shows [no of selected members] workspace members. <img width="643" height="283" alt="Screenshot 2025-12-17 at 8 01 23 PM" src="https://github.com/user-attachments/assets/18d524f4-979b-4d92-ad64-aa7b63be7897" /> <img width="774" height="309" alt="Screenshot 2025-12-17 at 8 01 33 PM" src="https://github.com/user-attachments/assets/779f374f-1501-48f9-afa2-a78628e067b1" /> <img width="737" height="397" alt="Screenshot 2025-12-17 at 8 01 40 PM" src="https://github.com/user-attachments/assets/4e8b963e-8a0f-467d-91ae-48bca4e1d842" /> <img width="697" height="334" alt="Screenshot 2025-12-17 at 8 01 53 PM" src="https://github.com/user-attachments/assets/c9a0e4bb-48b4-486b-a4f9-d7c49ff3852c" /> <img width="684" height="343" alt="Screenshot 2025-12-17 at 8 02 04 PM" src="https://github.com/user-attachments/assets/d5c45eba-06a3-40fc-b9d0-d585dc8bc136" /> --------- Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
@@ -103,6 +103,7 @@ export type LinksFilter = {
|
||||
export type ActorFilter = {
|
||||
name?: StringFilter;
|
||||
source?: SelectFilter;
|
||||
workspaceMemberId?: UUIDFilter;
|
||||
};
|
||||
|
||||
export type EmailsFilter = {
|
||||
|
||||
@@ -1153,6 +1153,71 @@ export const turnRecordFilterIntoRecordGqlOperationFilter = ({
|
||||
}
|
||||
}
|
||||
|
||||
if (subFieldName === 'workspaceMemberId') {
|
||||
const { isCurrentWorkspaceMemberSelected, selectedRecordIds } =
|
||||
jsonRelationFilterValueSchema
|
||||
.catch({
|
||||
isCurrentWorkspaceMemberSelected: false,
|
||||
selectedRecordIds: arrayOfUuidOrVariableSchema.parse(
|
||||
recordFilter.value,
|
||||
),
|
||||
})
|
||||
.parse(recordFilter.value);
|
||||
|
||||
const workspaceMemberIds = isCurrentWorkspaceMemberSelected
|
||||
? [
|
||||
...selectedRecordIds,
|
||||
filterValueDependencies?.currentWorkspaceMemberId,
|
||||
].filter(isDefined)
|
||||
: selectedRecordIds;
|
||||
|
||||
if (!isDefined(workspaceMemberIds) || workspaceMemberIds.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (recordFilter.operand) {
|
||||
case RecordFilterOperand.IS:
|
||||
return {
|
||||
[correspondingFieldMetadataItem.name]: {
|
||||
workspaceMemberId: {
|
||||
in: workspaceMemberIds,
|
||||
} satisfies UUIDFilter,
|
||||
},
|
||||
};
|
||||
case RecordFilterOperand.IS_NOT: {
|
||||
return {
|
||||
or: [
|
||||
{
|
||||
not: {
|
||||
[correspondingFieldMetadataItem.name]: {
|
||||
workspaceMemberId: {
|
||||
in: workspaceMemberIds,
|
||||
} satisfies UUIDFilter,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
[correspondingFieldMetadataItem.name]: {
|
||||
workspaceMemberId: {
|
||||
is: 'NULL',
|
||||
} satisfies UUIDFilter,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
default: {
|
||||
const fieldForRecordFilter = fieldMetadataItems.find(
|
||||
(field) => field.id === recordFilter.fieldMetadataId,
|
||||
);
|
||||
|
||||
throw new Error(
|
||||
`Unknown operand ${recordFilter.operand} for ${fieldForRecordFilter?.label ?? ''} filter`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (recordFilter.operand) {
|
||||
case RecordFilterOperand.CONTAINS:
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user