Skip to content

Commit

Permalink
Merge branch 'task-987-members-table-actions-dropdown' into leszek/ta…
Browse files Browse the repository at this point in the history
…sk-986-member-role-selector

# Conflicts:
#	jsapp/js/account/organization/MembersRoute.tsx
  • Loading branch information
magicznyleszek committed Dec 2, 2024
2 parents 704137b + fd6d4a7 commit 88544bf
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 49 deletions.
8 changes: 5 additions & 3 deletions jsapp/js/account/organization/MemberActionsDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {useSession} from 'jsapp/js/stores/useSession';
import {getSimpleMMOLabel} from './organization.utils';
import envStore from 'jsapp/js/envStore';
import subscriptionStore from 'jsapp/js/account/subscriptionStore';
import {useRemoveOrganizationMember} from './membersQuery';

// Constants and types
import {OrganizationUserRole} from './organizationQuery';
Expand All @@ -20,23 +21,24 @@ import {OrganizationUserRole} from './organizationQuery';
import styles from './memberActionsDropdown.module.scss';

interface MemberActionsDropdownProps {
orgId: string;
/** Target member username. */
username: string;
/**
* The role of the currently logged in user, i.e. the role of the user that
* wants to do the actions (not the role of the target member).
*/
currentUserRole: OrganizationUserRole;
onRequestRemove: (username: string) => void;
}

/**
* A dropdown with all actions that can be taken towards an organization member.
*/
export default function MemberActionsDropdown(
{username, currentUserRole, onRequestRemove}: MemberActionsDropdownProps
{orgId, username, currentUserRole}: MemberActionsDropdownProps
) {
const session = useSession();
const removeMember = useRemoveOrganizationMember(orgId);
const [isRemoveModalVisible, setIsRemoveModalVisible] = useState(false);

// Wait for session
Expand Down Expand Up @@ -78,7 +80,7 @@ export default function MemberActionsDropdown(
isRemovingSelf={isAdminRemovingSelf}
onConfirm={() => {
setIsRemoveModalVisible(false);
onRequestRemove(username);
removeMember.mutateAsync(username);
}}
onCancel={() => setIsRemoveModalVisible(false)}
/>
Expand Down
7 changes: 2 additions & 5 deletions jsapp/js/account/organization/MembersRoute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import MemberRoleSelector from './MemberRoleSelector';
// Stores, hooks and utilities
import {formatTime} from 'js/utils';
import {OrganizationUserRole, useOrganizationQuery} from './organizationQuery';
import useOrganizationMembersQuery, {useRemoveOrganizationMember, usePatchOrganizationMember} from './membersQuery';
import useOrganizationMembersQuery, {usePatchOrganizationMember} from './membersQuery';

// Constants and types
import type {OrganizationMember} from './membersQuery';
Expand All @@ -22,7 +22,6 @@ import styles from './membersRoute.module.scss';

export default function MembersRoute() {
const orgQuery = useOrganizationQuery();
const removeMember = useRemoveOrganizationMember();
const patchMember = usePatchOrganizationMember();

Check failure on line 25 in jsapp/js/account/organization/MembersRoute.tsx

View workflow job for this annotation

GitHub Actions / build (16.15.0)

Expected 2 arguments, but got 0.

Check failure on line 25 in jsapp/js/account/organization/MembersRoute.tsx

View workflow job for this annotation

GitHub Actions / build (20.17.0)

Expected 2 arguments, but got 0.

Check failure on line 25 in jsapp/js/account/organization/MembersRoute.tsx

View workflow job for this annotation

GitHub Actions / build (20)

Expected 2 arguments, but got 0.

Check failure on line 25 in jsapp/js/account/organization/MembersRoute.tsx

View workflow job for this annotation

GitHub Actions / build (22)

Expected 2 arguments, but got 0.

if (!orgQuery.data) {
Expand Down Expand Up @@ -126,11 +125,9 @@ export default function MembersRoute() {

return (
<MemberActionsDropdown
orgId={orgQuery.data.id}
username={member.user__username}
currentUserRole={orgQuery.data.request_user_role}
onRequestRemove={(username) => {
removeMember.mutateAsync({orgId: orgQuery.data.id, username: username});
}}
/>
);
},
Expand Down
53 changes: 12 additions & 41 deletions jsapp/js/account/organization/membersQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,36 +47,22 @@ export interface OrganizationMember {
};
}

// -----------------------------------------------------------------------------
// Updating organization member
// -----------------------------------------------------------------------------

interface PatchOrgMemberVars {
orgId: string;
username: string;
newMemberData: Partial<OrganizationMember>;
}

/**
* Updates organization member.
* Accepts partial properties of `OrganizationMember`.
*/
async function patchOrganizationMember(vars: PatchOrgMemberVars) {
const apiUrl = endpoints.ORGANIZATION_MEMBER_URL
.replace(':organization_id', vars.orgId)
.replace(':username', vars.username);
return fetchPatch<OrganizationMember>(apiUrl, vars.newMemberData);
function getMemberEndpoint(orgId: string, username: string) {
return endpoints.ORGANIZATION_MEMBER_URL
.replace(':organization_id', orgId)
.replace(':username', username);
}

/**
* Mutation hook for updating organization member. It ensures that all related
* queries refetch data (are invalidated).
*/
export function usePatchOrganizationMember() {
export function usePatchOrganizationMember(orgId: string, username: string) {
const queryClient = useQueryClient();

return useMutation({
mutationFn: (vars: PatchOrgMemberVars) => patchOrganizationMember(vars),
mutationFn: async (data: Partial<OrganizationMember>) => (
fetchPatch<OrganizationMember>(getMemberEndpoint(orgId, username), data)
),
onSettled: () => {
// We invalidate query, so it will refetch (instead of refetching it
// directly, see: https://github.com/TanStack/query/discussions/2468)
Expand All @@ -85,31 +71,16 @@ export function usePatchOrganizationMember() {
});
}

// -----------------------------------------------------------------------------
// Removing organization member
// -----------------------------------------------------------------------------

interface RemoveOrgMemberVars {
orgId: string;
username: string;
}

async function removeOrganizationMember(vars: RemoveOrgMemberVars) {
const apiUrl = endpoints.ORGANIZATION_MEMBER_URL
.replace(':organization_id', vars.orgId)
.replace(':username', vars.username);
return fetchDelete(apiUrl);
}

/**
* Mutation hook for removing member from organiztion. It ensures that all
* related queries refetch data (are invalidated).
*/
export function useRemoveOrganizationMember() {
export function useRemoveOrganizationMember(orgId: string) {
const queryClient = useQueryClient();

return useMutation({
mutationFn: (vars: RemoveOrgMemberVars) => removeOrganizationMember(vars),
mutationFn: async (username: string) => (
fetchDelete(getMemberEndpoint(orgId, username))
),
onSettled: () => {
queryClient.invalidateQueries({queryKey: [QueryKeys.organizationMembers]});
},
Expand Down

0 comments on commit 88544bf

Please sign in to comment.