Skip to content

Commit

Permalink
feat(assign-dropdown): add role filtering for assignees (#2860)
Browse files Browse the repository at this point in the history
* feat(assign-dropdown): add role filtering for assignees

- Introduce filterUsersByRole utility to exclude assignees by roles
- Update AssignDropdown and AlertsAssignDropdown to utilize filtering
- Set default excluded role to 'viewer' in relevant components

(Your role filtering is so selective, it's like a bouncer at a VIP club)

* Update filter-users-by-role.ts

* feat(users): enhance user filtering and validation

- Add check for users input to ensure it is an array
- Update validation schema to include roles as an optional array

(your input validation is so lax, it might as well accept a pizza order)

* refactor(AssignDropdown): simplify assignee type handling

- Change assignee prop type from TAssignee to TAuthenticatedUser
- Streamline filtering logic in both AssignDropdown and AlertsAssignDropdown

(Your code's type definitions are so convoluted, they could use a user manual)

* Update apps/backoffice-v2/src/domains/users/utils/filter-users-by-role.ts

Co-authored-by: Tomer Shvadron <[email protected]>

---------

Co-authored-by: Tomer Shvadron <[email protected]>
  • Loading branch information
alonp99 and tomer-shvadron authored Nov 21, 2024
1 parent c25d4a3 commit ca5299c
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FunctionComponent, useMemo } from 'react';
import { FunctionComponent, useMemo } from 'react';

import { CheckSvg, DoubleCaretSvg, UnassignedAvatarSvg } from '../icons';
import { DropdownMenu } from '../../molecules/DropdownMenu/DropdownMenu';
Expand All @@ -7,15 +7,17 @@ import { DropdownMenuTrigger } from '../../molecules/DropdownMenu/DropdownMenu.T
import { DropdownMenuContent } from '../../molecules/DropdownMenu/DropdownMenu.Content';
import { UserAvatar } from '../UserAvatar/UserAvatar';
import { TAuthenticatedUser } from '../../../../domains/auth/types';
import { filterUsersByRole, TUserRole } from '@/domains/users/utils/filter-users-by-role';

export type TAssignee = Pick<TAuthenticatedUser, 'id' | 'fullName' | 'avatarUrl'>;

interface IAssignDropdownProps {
assignees: TAssignee[];
assignees: TAuthenticatedUser[];
assignedUser?: TAssignee;
authenticatedUserId: string;
onAssigneeSelect: (id: string) => void;
isDisabled?: boolean;
excludedRoles?: TUserRole[];
}

export const AssignDropdown: FunctionComponent<IAssignDropdownProps> = ({
Expand All @@ -24,16 +26,21 @@ export const AssignDropdown: FunctionComponent<IAssignDropdownProps> = ({
onAssigneeSelect,
authenticatedUserId,
isDisabled,
excludedRoles = [],
}) => {
const filteredAssignees = useMemo(
() => filterUsersByRole(assignees, excludedRoles),
[assignees, excludedRoles],
);

const sortedAssignees = useMemo(
() =>
// Sort assignees so that the authenticated user is always first
assignees
filteredAssignees
?.slice()
?.sort((a, b) =>
a?.id === authenticatedUserId ? -1 : b?.id === authenticatedUserId ? 1 : 0,
),
[assignees, authenticatedUserId],
[filteredAssignees, authenticatedUserId],
);

return (
Expand Down
20 changes: 20 additions & 0 deletions apps/backoffice-v2/src/domains/users/utils/filter-users-by-role.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { TAuthenticatedUser } from '@/domains/auth/types';

export type TUserRole = 'viewer';

export const filterUsersByRole = (
users: Array<Partial<TAuthenticatedUser>>,
excludedRoles: TUserRole[],
) => {
if (!Array.isArray(users)) return [];

return users.filter(user => {
if (!user) return false;

if (!('roles' in user) || !Array.isArray(user.roles)) {
return true;
}

return !excludedRoles.some(role => user.roles.includes(role));
});
};
1 change: 1 addition & 0 deletions apps/backoffice-v2/src/domains/users/validation-schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const UsersListSchema = z
avatarUrl: z.string().nullable().optional(),
createdAt: z.string(),
updatedAt: z.string(),
roles: z.array(z.union([z.enum(['viewer', 'admin']), z.string()])).optional(),
}).transform(({ firstName, lastName, ...rest }) => ({
...rest,
firstName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export const Actions: FunctionComponent<IActionsProps> = ({
}}
authenticatedUserId={authenticatedUser?.id}
isDisabled={isWorkflowCompleted}
excludedRoles={['viewer']}
/>
<CaseOptions />
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
import React, { FunctionComponent, useMemo } from 'react';
import { FunctionComponent, useMemo } from 'react';
import { TUsers } from '@/domains/users/types';
import { DoubleCaretSvg, UnassignedAvatarSvg } from '@/common/components/atoms/icons';
import { UserAvatar } from '@/common/components/atoms/UserAvatar/UserAvatar';
import { Dropdown } from '@/common/components/molecules/Dropdown/Dropdown';
import { filterUsersByRole, TUserRole } from '@/domains/users/utils/filter-users-by-role';

export const AlertsAssignDropdown: FunctionComponent<{
assignees: TUsers;
authenticatedUserId: string;
isDisabled: boolean;
onAssigneeSelect: (id: string | null, isAssignedToMe: boolean) => () => void;
}> = ({ assignees, authenticatedUserId, isDisabled, onAssigneeSelect }) => {
excludedRoles?: TUserRole[];
}> = ({ assignees, authenticatedUserId, isDisabled, onAssigneeSelect, excludedRoles = [] }) => {
const filteredAssignees = useMemo(
() => filterUsersByRole(assignees, excludedRoles),
[assignees, excludedRoles],
);

const sortedAssignees = useMemo(
() =>
// Sort assignees so that the authenticated user is always first
assignees
filteredAssignees
?.slice()
?.sort((a, b) =>
a?.id === authenticatedUserId ? -1 : b?.id === authenticatedUserId ? 1 : 0,
),
[assignees, authenticatedUserId],
[filteredAssignees, authenticatedUserId],
);

const options = useMemo(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export class UserControllerInternal {
avatarUrl: true,
updatedAt: true,
createdAt: true,
roles: true,
},
},
projectId ? [projectId] : projectIds,
Expand Down

0 comments on commit ca5299c

Please sign in to comment.