Skip to content

Commit

Permalink
feat(organizations): member role selector TASK-986 (#5315)
Browse files Browse the repository at this point in the history
### πŸ“£ Summary
In Members Table (from Account β†’ Team/Organization β†’ Members) add UI for
changing member's role.

### πŸ“– Description
Only owner and admins can modify the role.

### πŸ‘€ Preview steps
1. ℹ️ have multiple different users
2. for one of the users (e.g. "joe"), use
http://kf.kobo.local/admin/organizations/organization/ to add multiple
users into joe's organization
3. For one of the users (e.g. "sue") set the role to "admin"
4. enable "Multi-members override" for joe's organization
5. enable feature flag `mmosEnabled`
6. navigate to `#/account/organization/members` (as "joe")
7. 🟒 notice that in the table there is no way to change "joe" (owner)
role
8. 🟒 notice that in the table you can change any other user role

As continuation for above steps:
1. log in as "sue"
2. navigate to `#/account/organization/members`
3. 🟒 notice (again) that in the table there is no way to change "joe"
(owner) role (even though you're an "admin")
4. 🟒 notice that for "sue" you can change the role (to stop being an
admin)

### πŸ’­ Notes
Build atop #5309
  • Loading branch information
magicznyleszek authored Dec 11, 2024
1 parent af28266 commit 8094a92
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
48 changes: 48 additions & 0 deletions jsapp/js/account/organization/MemberRoleSelector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import KoboSelect from 'jsapp/js/components/common/koboSelect';
import {usePatchOrganizationMember} from './membersQuery';
import {OrganizationUserRole} from './organizationQuery';

interface MemberRoleSelectorProps {
username: string;
/** The role of the `username` user - the one we are modifying here. */
role: OrganizationUserRole;
/** The role of the currently logged in user. */
currentUserRole: OrganizationUserRole;
}

export default function MemberRoleSelector(
{username, role, currentUserRole}: MemberRoleSelectorProps
) {
const patchMember = usePatchOrganizationMember(username);

const canModifyRole = (
currentUserRole === 'owner' ||
currentUserRole === 'admin'
);

return (
<KoboSelect
name={`member-role-selector-${username}`}
type='outline'
size='m'
options={[
{
value: OrganizationUserRole.admin,
label: t('Admin'),
},
{
value: OrganizationUserRole.member,
label: t('Member'),
},
]}
selectedOption={role}
onChange={(newRole: string | null) => {
if (newRole) {
patchMember.mutateAsync({role: newRole as OrganizationUserRole});
}
}}
isPending={patchMember.isPending}
isDisabled={!canModifyRole}
/>
);
}
13 changes: 13 additions & 0 deletions jsapp/js/account/organization/MembersRoute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import LoadingSpinner from 'js/components/common/loadingSpinner';
import Avatar from 'js/components/common/avatar';
import Badge from 'jsapp/js/components/common/badge';
import MemberActionsDropdown from './MemberActionsDropdown';
import MemberRoleSelector from './MemberRoleSelector';

// Stores, hooks and utilities
import {formatTime} from 'js/utils';
Expand Down Expand Up @@ -67,6 +68,18 @@ export default function MembersRoute() {
key: 'role',
label: t('Role'),
size: 120,
cellFormatter: (member: OrganizationMember) => {
if (member.role === OrganizationUserRole.owner) {
return t('Owner');
}
return (
<MemberRoleSelector
username={member.user__username}
role={member.role}
currentUserRole={orgQuery.data.request_user_role}
/>
);
},
},
{
key: 'user__has_mfa_enabled',
Expand Down

0 comments on commit 8094a92

Please sign in to comment.