From ad98bf45cc1ef8048e71224699c59a786a3df1d2 Mon Sep 17 00:00:00 2001 From: Chewbacca Date: Mon, 20 Mar 2023 15:40:21 -0400 Subject: [PATCH] Add hook to delete Group --- .../entity-store/hooks/useEntityActions.ts | 16 ++++++++--- .../group/components/group-action-button.tsx | 28 ++++++++++--------- app/soapbox/features/group/manage-group.tsx | 26 +++++++++++++---- .../hooks/api/groups/useDeleteGroup.ts | 18 ++++++++++++ app/soapbox/hooks/api/index.ts | 1 + 5 files changed, 67 insertions(+), 22 deletions(-) create mode 100644 app/soapbox/hooks/api/groups/useDeleteGroup.ts diff --git a/app/soapbox/entity-store/hooks/useEntityActions.ts b/app/soapbox/entity-store/hooks/useEntityActions.ts index 2383c69c64..3a60f46276 100644 --- a/app/soapbox/entity-store/hooks/useEntityActions.ts +++ b/app/soapbox/entity-store/hooks/useEntityActions.ts @@ -30,7 +30,7 @@ interface EntityActionEndpoints { } interface EntityCallbacks { - onSuccess?(entity: TEntity): void + onSuccess?(entity?: TEntity): void } function useEntityActions( @@ -70,14 +70,20 @@ function useEntityActions( }); } - function deleteEntity(entityId: string): Promise { + function deleteEntity(entityId: string, callbacks: EntityCallbacks = {}): Promise { if (!endpoints.delete) return Promise.reject(endpoints); // Get the entity before deleting, so we can reverse the action if the API request fails. const entity = getState().entities[entityType]?.store[entityId]; // Optimistically delete the entity from the _store_ but keep the lists in tact. dispatch(deleteEntities([entityId], entityType, { preserveLists: true })); + setIsLoading(true); + return api.delete(endpoints.delete.replaceAll(':id', entityId)).then((response) => { + if (callbacks.onSuccess) { + callbacks.onSuccess(); + } + // Success - finish deleting entity from the state. dispatch(deleteEntities([entityId], entityType)); @@ -90,12 +96,14 @@ function useEntityActions( dispatch(importEntities([entity], entityType)); } throw e; + }).finally(() => { + setIsLoading(false); }); } return { - createEntity: createEntity, - deleteEntity: endpoints.delete ? deleteEntity : undefined, + createEntity, + deleteEntity, isLoading, }; } diff --git a/app/soapbox/features/group/components/group-action-button.tsx b/app/soapbox/features/group/components/group-action-button.tsx index ba828c9c1b..8c8a36db76 100644 --- a/app/soapbox/features/group/components/group-action-button.tsx +++ b/app/soapbox/features/group/components/group-action-button.tsx @@ -7,8 +7,10 @@ import { deleteEntities } from 'soapbox/entity-store/actions'; import { Entities } from 'soapbox/entity-store/entities'; import { useAppDispatch } from 'soapbox/hooks'; import { useCancelMembershipRequest, useJoinGroup, useLeaveGroup } from 'soapbox/hooks/api'; +import { GroupRoles } from 'soapbox/schemas/group-member'; import toast from 'soapbox/toast'; -import { Group } from 'soapbox/types/entities'; + +import type { Group } from 'soapbox/types/entities'; interface IGroupActionButton { group: Group @@ -33,7 +35,7 @@ const GroupActionButton = ({ group }: IGroupActionButton) => { const isRequested = group.relationship?.requested; const isNonMember = !group.relationship?.member && !isRequested; - const isAdmin = group.relationship?.role === 'owner'; + const isOwner = group.relationship?.role === GroupRoles.OWNER; const isBlocked = group.relationship?.blocked_by; const onJoinGroup = () => joinGroup.mutate({}, { @@ -68,6 +70,17 @@ const GroupActionButton = ({ group }: IGroupActionButton) => { return null; } + if (isOwner) { + return ( + + ); + } + if (isNonMember) { return ( - ); - } - return (