Files
twenty/packages/twenty-front/src/pages/settings/roles/components/RoleWorkspaceMemberPickerDropdownContent.tsx
T
Weiko 02ced028e5 add role assignment page (#10115)
## Context
This PR introduces the "assignment" tab in the Role edit page, currently
allowing admin users to assign workspace members to specific roles.

Note: For now, a user can only have one role and a modal will warn you
if you try to re-assign a user to a new role.

## Test
<img width="648" alt="Screenshot 2025-02-10 at 17 59 21"
src="https://github.com/user-attachments/assets/dabd7a17-6aca-4d2b-95d8-46182f53e1e8"
/>
<img width="668" alt="Screenshot 2025-02-10 at 17 59 33"
src="https://github.com/user-attachments/assets/802aab7a-db67-4f83-9a44-35773df100f7"
/>
<img width="629" alt="Screenshot 2025-02-10 at 17 59 42"
src="https://github.com/user-attachments/assets/277db061-3f05-4ccd-8a83-7a96d6c1673e"
/>
2025-02-11 14:51:31 +01:00

84 lines
2.3 KiB
TypeScript

import styled from '@emotion/styled';
import { t } from '@lingui/core/macro';
import { Avatar } from 'twenty-ui';
import { WorkspaceMember } from '~/generated-metadata/graphql';
const StyledEmptyState = styled.div`
align-items: center;
color: ${({ theme }) => theme.font.color.light};
display: flex;
font-size: ${({ theme }) => theme.font.size.md};
font-weight: ${({ theme }) => theme.font.weight.regular};
height: ${({ theme }) => theme.spacing(8)};
justify-content: flex-start;
padding: ${({ theme }) => theme.spacing(2)};
`;
const StyledWorkspaceMemberItem = styled.div`
align-items: center;
cursor: pointer;
display: flex;
font-size: ${({ theme }) => theme.font.size.md};
gap: ${({ theme }) => theme.spacing(2)};
min-width: ${({ theme }) => theme.spacing(45)};
padding: ${({ theme }) => theme.spacing(2)};
&:hover {
background: ${({ theme }) => theme.background.tertiary};
}
`;
const StyledWorkspaceMemberName = styled.div`
color: ${({ theme }) => theme.font.color.secondary};
`;
type RoleWorkspaceMemberPickerDropdownContentProps = {
loading: boolean;
searchFilter: string;
filteredWorkspaceMembers: WorkspaceMember[];
onSelect: (workspaceMember: WorkspaceMember) => void;
};
export const RoleWorkspaceMemberPickerDropdownContent = ({
loading,
searchFilter,
filteredWorkspaceMembers,
onSelect,
}: RoleWorkspaceMemberPickerDropdownContentProps) => {
if (loading) {
return null;
}
if (!filteredWorkspaceMembers?.length) {
return (
<StyledEmptyState>
{searchFilter
? t`No members matching this search`
: t`No more members to add`}
</StyledEmptyState>
);
}
return (
<>
{filteredWorkspaceMembers.map((workspaceMember) => (
<StyledWorkspaceMemberItem
key={workspaceMember.id}
onClick={() => onSelect(workspaceMember)}
aria-label={`${workspaceMember.name.firstName} ${workspaceMember.name.lastName}`}
>
<Avatar
type="rounded"
size="md"
placeholderColorSeed={workspaceMember.id}
placeholder={workspaceMember.name.firstName ?? ''}
/>
<StyledWorkspaceMemberName>
{workspaceMember.name.firstName} {workspaceMember.name.lastName}
</StyledWorkspaceMemberName>
</StyledWorkspaceMemberItem>
))}
</>
);
};