pl-fe: remove user lists reducer
Signed-off-by: mkljczk <git@mkljczk.pl>
This commit is contained in:
parent
105c87c64d
commit
05bb838577
9 changed files with 68 additions and 205 deletions
|
@ -1,99 +1,12 @@
|
||||||
import { getClient } from '../api';
|
import { getClient } from '../api';
|
||||||
|
|
||||||
import { importEntities } from './importer';
|
|
||||||
|
|
||||||
import type { Account, PaginatedResponse } from 'pl-api';
|
|
||||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||||
|
|
||||||
const GROUP_BLOCKS_FETCH_REQUEST = 'GROUP_BLOCKS_FETCH_REQUEST' as const;
|
|
||||||
const GROUP_BLOCKS_FETCH_SUCCESS = 'GROUP_BLOCKS_FETCH_SUCCESS' as const;
|
|
||||||
const GROUP_BLOCKS_FETCH_FAIL = 'GROUP_BLOCKS_FETCH_FAIL' as const;
|
|
||||||
|
|
||||||
const GROUP_UNBLOCK_REQUEST = 'GROUP_UNBLOCK_REQUEST' as const;
|
|
||||||
const GROUP_UNBLOCK_SUCCESS = 'GROUP_UNBLOCK_SUCCESS' as const;
|
|
||||||
const GROUP_UNBLOCK_FAIL = 'GROUP_UNBLOCK_FAIL' as const;
|
|
||||||
|
|
||||||
const groupKick = (groupId: string, accountId: string) =>
|
const groupKick = (groupId: string, accountId: string) =>
|
||||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
(dispatch: AppDispatch, getState: () => RootState) => {
|
||||||
return getClient(getState).experimental.groups.kickGroupUsers(groupId, [accountId]);
|
return getClient(getState).experimental.groups.kickGroupUsers(groupId, [accountId]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchGroupBlocks = (groupId: string) =>
|
|
||||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
|
||||||
dispatch(fetchGroupBlocksRequest(groupId));
|
|
||||||
|
|
||||||
return getClient(getState).experimental.groups.getGroupBlocks(groupId).then(response => {
|
|
||||||
dispatch(importEntities({ accounts: response.items }));
|
|
||||||
dispatch(fetchGroupBlocksSuccess(groupId, response.items, response.next));
|
|
||||||
}).catch(error => {
|
|
||||||
dispatch(fetchGroupBlocksFail(groupId, error));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const fetchGroupBlocksRequest = (groupId: string) => ({
|
|
||||||
type: GROUP_BLOCKS_FETCH_REQUEST,
|
|
||||||
groupId,
|
|
||||||
});
|
|
||||||
|
|
||||||
const fetchGroupBlocksSuccess = (groupId: string, accounts: Array<Account>, next: (() => Promise<PaginatedResponse<Account>>) | null) => ({
|
|
||||||
type: GROUP_BLOCKS_FETCH_SUCCESS,
|
|
||||||
groupId,
|
|
||||||
accounts,
|
|
||||||
next,
|
|
||||||
});
|
|
||||||
|
|
||||||
const fetchGroupBlocksFail = (groupId: string, error: unknown) => ({
|
|
||||||
type: GROUP_BLOCKS_FETCH_FAIL,
|
|
||||||
groupId,
|
|
||||||
error,
|
|
||||||
skipNotFound: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const groupUnblock = (groupId: string, accountId: string) =>
|
|
||||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
|
||||||
dispatch(groupUnblockRequest(groupId, accountId));
|
|
||||||
|
|
||||||
return getClient(getState).experimental.groups.unblockGroupUsers(groupId, [accountId])
|
|
||||||
.then(() => dispatch(groupUnblockSuccess(groupId, accountId)))
|
|
||||||
.catch(err => dispatch(groupUnblockFail(groupId, accountId, err)));
|
|
||||||
};
|
|
||||||
|
|
||||||
const groupUnblockRequest = (groupId: string, accountId: string) => ({
|
|
||||||
type: GROUP_UNBLOCK_REQUEST,
|
|
||||||
groupId,
|
|
||||||
accountId,
|
|
||||||
});
|
|
||||||
|
|
||||||
const groupUnblockSuccess = (groupId: string, accountId: string) => ({
|
|
||||||
type: GROUP_UNBLOCK_SUCCESS,
|
|
||||||
groupId,
|
|
||||||
accountId,
|
|
||||||
});
|
|
||||||
|
|
||||||
const groupUnblockFail = (groupId: string, accountId: string, error: unknown) => ({
|
|
||||||
type: GROUP_UNBLOCK_FAIL,
|
|
||||||
groupId,
|
|
||||||
accountId,
|
|
||||||
error,
|
|
||||||
});
|
|
||||||
|
|
||||||
type GroupsAction =
|
|
||||||
| ReturnType<typeof fetchGroupBlocksRequest>
|
|
||||||
| ReturnType<typeof fetchGroupBlocksSuccess>
|
|
||||||
| ReturnType<typeof fetchGroupBlocksFail>
|
|
||||||
| ReturnType<typeof groupUnblockRequest>
|
|
||||||
| ReturnType<typeof groupUnblockSuccess>
|
|
||||||
| ReturnType<typeof groupUnblockFail>
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
GROUP_BLOCKS_FETCH_REQUEST,
|
|
||||||
GROUP_BLOCKS_FETCH_SUCCESS,
|
|
||||||
GROUP_BLOCKS_FETCH_FAIL,
|
|
||||||
GROUP_UNBLOCK_REQUEST,
|
|
||||||
GROUP_UNBLOCK_SUCCESS,
|
|
||||||
GROUP_UNBLOCK_FAIL,
|
|
||||||
groupKick,
|
groupKick,
|
||||||
fetchGroupBlocks,
|
|
||||||
groupUnblock,
|
|
||||||
type GroupsAction,
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
import { Entities } from 'pl-fe/entity-store/entities';
|
|
||||||
import { useCreateEntity } from 'pl-fe/entity-store/hooks/use-create-entity';
|
|
||||||
import { useClient } from 'pl-fe/hooks/use-client';
|
|
||||||
|
|
||||||
import type { Group } from 'pl-api';
|
|
||||||
import type { Account } from 'pl-fe/normalizers/account';
|
|
||||||
|
|
||||||
const useBlockGroupMember = (group: Pick<Group, 'id'>, account: Pick<Account, 'id'>) => {
|
|
||||||
const client = useClient();
|
|
||||||
|
|
||||||
const { createEntity } = useCreateEntity(
|
|
||||||
[Entities.GROUP_MEMBERSHIPS, account.id],
|
|
||||||
(accountIds: string[]) => client.experimental.groups.blockGroupUsers(group.id, accountIds),
|
|
||||||
);
|
|
||||||
|
|
||||||
return createEntity;
|
|
||||||
};
|
|
||||||
|
|
||||||
export { useBlockGroupMember };
|
|
|
@ -13,7 +13,6 @@ import { initReport, ReportableEntities } from 'pl-fe/actions/reports';
|
||||||
import { changeSetting } from 'pl-fe/actions/settings';
|
import { changeSetting } from 'pl-fe/actions/settings';
|
||||||
import { deleteStatus, editStatus, toggleMuteStatus } from 'pl-fe/actions/statuses';
|
import { deleteStatus, editStatus, toggleMuteStatus } from 'pl-fe/actions/statuses';
|
||||||
import { deleteFromTimelines } from 'pl-fe/actions/timelines';
|
import { deleteFromTimelines } from 'pl-fe/actions/timelines';
|
||||||
import { useBlockGroupMember } from 'pl-fe/api/hooks/groups/use-block-group-member';
|
|
||||||
import { useDeleteGroupStatus } from 'pl-fe/api/hooks/groups/use-delete-group-status';
|
import { useDeleteGroupStatus } from 'pl-fe/api/hooks/groups/use-delete-group-status';
|
||||||
import { useGroup } from 'pl-fe/api/hooks/groups/use-group';
|
import { useGroup } from 'pl-fe/api/hooks/groups/use-group';
|
||||||
import { useGroupRelationship } from 'pl-fe/api/hooks/groups/use-group-relationship';
|
import { useGroupRelationship } from 'pl-fe/api/hooks/groups/use-group-relationship';
|
||||||
|
@ -30,6 +29,7 @@ import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
|
import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
|
||||||
import { useSettings } from 'pl-fe/hooks/use-settings';
|
import { useSettings } from 'pl-fe/hooks/use-settings';
|
||||||
import { useChats } from 'pl-fe/queries/chats';
|
import { useChats } from 'pl-fe/queries/chats';
|
||||||
|
import { useBlockGroupUserMutation } from 'pl-fe/queries/groups/use-group-blocks';
|
||||||
import { useTranslationLanguages } from 'pl-fe/queries/instance/use-translation-languages';
|
import { useTranslationLanguages } from 'pl-fe/queries/instance/use-translation-languages';
|
||||||
import { RootState } from 'pl-fe/store';
|
import { RootState } from 'pl-fe/store';
|
||||||
import { useModalsStore } from 'pl-fe/stores/modals';
|
import { useModalsStore } from 'pl-fe/stores/modals';
|
||||||
|
@ -590,7 +590,7 @@ const MenuButton: React.FC<IMenuButton> = ({
|
||||||
const { openModal } = useModalsStore();
|
const { openModal } = useModalsStore();
|
||||||
const { group } = useGroup((status.group as Group)?.id as string);
|
const { group } = useGroup((status.group as Group)?.id as string);
|
||||||
const deleteGroupStatus = useDeleteGroupStatus(group as Group, status.id);
|
const deleteGroupStatus = useDeleteGroupStatus(group as Group, status.id);
|
||||||
const blockGroupMember = useBlockGroupMember(group as Group, status.account);
|
const { mutate: blockGroupMember } = useBlockGroupUserMutation(status.group?.id as string, status.account.id);
|
||||||
const { getOrCreateChatByAccountId } = useChats();
|
const { getOrCreateChatByAccountId } = useChats();
|
||||||
|
|
||||||
const { groupRelationship } = useGroupRelationship(status.group_id || undefined);
|
const { groupRelationship } = useGroupRelationship(status.group_id || undefined);
|
||||||
|
@ -762,8 +762,8 @@ const MenuButton: React.FC<IMenuButton> = ({
|
||||||
message: intl.formatMessage(messages.groupBlockFromGroupMessage, { name: status.account.username }),
|
message: intl.formatMessage(messages.groupBlockFromGroupMessage, { name: status.account.username }),
|
||||||
confirm: intl.formatMessage(messages.groupBlockConfirm),
|
confirm: intl.formatMessage(messages.groupBlockConfirm),
|
||||||
onConfirm: () => {
|
onConfirm: () => {
|
||||||
blockGroupMember([status.account_id], {
|
blockGroupMember(undefined, {
|
||||||
onSuccess() {
|
onSuccess: () => {
|
||||||
toast.success(intl.formatMessage(messages.blocked, { name: account?.acct }));
|
toast.success(intl.formatMessage(messages.blocked, { name: account?.acct }));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,7 +5,6 @@ import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { groupKick } from 'pl-fe/actions/groups';
|
import { groupKick } from 'pl-fe/actions/groups';
|
||||||
import { useAccount } from 'pl-fe/api/hooks/accounts/use-account';
|
import { useAccount } from 'pl-fe/api/hooks/accounts/use-account';
|
||||||
import { useBlockGroupMember } from 'pl-fe/api/hooks/groups/use-block-group-member';
|
|
||||||
import { useDemoteGroupMember } from 'pl-fe/api/hooks/groups/use-demote-group-member';
|
import { useDemoteGroupMember } from 'pl-fe/api/hooks/groups/use-demote-group-member';
|
||||||
import { usePromoteGroupMember } from 'pl-fe/api/hooks/groups/use-promote-group-member';
|
import { usePromoteGroupMember } from 'pl-fe/api/hooks/groups/use-promote-group-member';
|
||||||
import Account from 'pl-fe/components/account';
|
import Account from 'pl-fe/components/account';
|
||||||
|
@ -15,6 +14,7 @@ import { deleteEntities } from 'pl-fe/entity-store/actions';
|
||||||
import { Entities } from 'pl-fe/entity-store/entities';
|
import { Entities } from 'pl-fe/entity-store/entities';
|
||||||
import PlaceholderAccount from 'pl-fe/features/placeholder/components/placeholder-account';
|
import PlaceholderAccount from 'pl-fe/features/placeholder/components/placeholder-account';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
|
import { useBlockGroupUserMutation } from 'pl-fe/queries/groups/use-group-blocks';
|
||||||
import { useModalsStore } from 'pl-fe/stores/modals';
|
import { useModalsStore } from 'pl-fe/stores/modals';
|
||||||
import toast from 'pl-fe/toast';
|
import toast from 'pl-fe/toast';
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ const GroupMemberListItem = ({ member, group }: IGroupMemberListItem) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { openModal } = useModalsStore();
|
const { openModal } = useModalsStore();
|
||||||
|
|
||||||
const blockGroupMember = useBlockGroupMember(group, member.account);
|
const { mutate: blockGroupMember } = useBlockGroupUserMutation(group.id, member.account.id);
|
||||||
const promoteGroupMember = usePromoteGroupMember(group, member);
|
const promoteGroupMember = usePromoteGroupMember(group, member);
|
||||||
const demoteGroupMember = useDemoteGroupMember(group, member);
|
const demoteGroupMember = useDemoteGroupMember(group, member);
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ const GroupMemberListItem = ({ member, group }: IGroupMemberListItem) => {
|
||||||
message: intl.formatMessage(messages.blockFromGroupMessage, { name: account?.username }),
|
message: intl.formatMessage(messages.blockFromGroupMessage, { name: account?.username }),
|
||||||
confirm: intl.formatMessage(messages.blockConfirm),
|
confirm: intl.formatMessage(messages.blockConfirm),
|
||||||
onConfirm: () => {
|
onConfirm: () => {
|
||||||
blockGroupMember([member.account.id], {
|
blockGroupMember(undefined, {
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
dispatch(deleteEntities([member.id], Entities.GROUP_MEMBERSHIPS));
|
dispatch(deleteEntities([member.id], Entities.GROUP_MEMBERSHIPS));
|
||||||
toast.success(intl.formatMessage(messages.blocked, { name: account?.acct }));
|
toast.success(intl.formatMessage(messages.blocked, { name: account?.acct }));
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import React, { useEffect } from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { fetchGroupBlocks, groupUnblock } from 'pl-fe/actions/groups';
|
|
||||||
import { useAccount } from 'pl-fe/api/hooks/accounts/use-account';
|
import { useAccount } from 'pl-fe/api/hooks/accounts/use-account';
|
||||||
import { useGroup } from 'pl-fe/api/hooks/groups/use-group';
|
import { useGroup } from 'pl-fe/api/hooks/groups/use-group';
|
||||||
import Account from 'pl-fe/components/account';
|
import Account from 'pl-fe/components/account';
|
||||||
|
@ -10,8 +9,7 @@ import Button from 'pl-fe/components/ui/button';
|
||||||
import Column from 'pl-fe/components/ui/column';
|
import Column from 'pl-fe/components/ui/column';
|
||||||
import HStack from 'pl-fe/components/ui/hstack';
|
import HStack from 'pl-fe/components/ui/hstack';
|
||||||
import Spinner from 'pl-fe/components/ui/spinner';
|
import Spinner from 'pl-fe/components/ui/spinner';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useGroupBlocks, useUnblockGroupUserMutation } from 'pl-fe/queries/groups/use-group-blocks';
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
|
||||||
import toast from 'pl-fe/toast';
|
import toast from 'pl-fe/toast';
|
||||||
|
|
||||||
import ColumnForbidden from '../ui/components/column-forbidden';
|
import ColumnForbidden from '../ui/components/column-forbidden';
|
||||||
|
@ -31,14 +29,16 @@ interface IBlockedMember {
|
||||||
|
|
||||||
const BlockedMember: React.FC<IBlockedMember> = ({ accountId, groupId }) => {
|
const BlockedMember: React.FC<IBlockedMember> = ({ accountId, groupId }) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const { account } = useAccount(accountId);
|
const { account } = useAccount(accountId);
|
||||||
|
|
||||||
|
const { mutate: unblockGroupUser } = useUnblockGroupUserMutation(groupId, accountId);
|
||||||
|
|
||||||
if (!account) return null;
|
if (!account) return null;
|
||||||
|
|
||||||
const handleUnblock = () =>
|
const handleUnblock = () =>
|
||||||
dispatch(groupUnblock(groupId, accountId))
|
unblockGroupUser(undefined, {
|
||||||
.then(() => toast.success(intl.formatMessage(messages.unblocked, { name: account.acct })));
|
onSuccess: () => toast.success(intl.formatMessage(messages.unblocked, { name: account.acct })),
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HStack space={1} alignItems='center' justifyContent='between' className='p-2.5'>
|
<HStack space={1} alignItems='center' justifyContent='between' className='p-2.5'>
|
||||||
|
@ -61,16 +61,11 @@ interface IGroupBlockedMembers {
|
||||||
|
|
||||||
const GroupBlockedMembers: React.FC<IGroupBlockedMembers> = ({ params }) => {
|
const GroupBlockedMembers: React.FC<IGroupBlockedMembers> = ({ params }) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
|
|
||||||
const groupId = params?.groupId;
|
const groupId = params?.groupId;
|
||||||
|
|
||||||
const { group } = useGroup(groupId);
|
const { group } = useGroup(groupId);
|
||||||
const accountIds = useAppSelector((state) => state.user_lists.group_blocks[groupId]?.items);
|
const { data: accountIds } = useGroupBlocks(groupId);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
dispatch(fetchGroupBlocks(groupId));
|
|
||||||
}, [groupId]);
|
|
||||||
|
|
||||||
if (!group || !group.relationship || !accountIds) {
|
if (!group || !group.relationship || !accountIds) {
|
||||||
return (
|
return (
|
||||||
|
|
53
packages/pl-fe/src/queries/groups/use-group-blocks.ts
Normal file
53
packages/pl-fe/src/queries/groups/use-group-blocks.ts
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
import { useMutation, type InfiniteData } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
import { makePaginatedResponseQuery } from 'pl-fe/api/utils/make-paginated-response-query';
|
||||||
|
import { minifyAccountList } from 'pl-fe/api/utils/minify-list';
|
||||||
|
import { useClient } from 'pl-fe/hooks/use-client';
|
||||||
|
import { queryClient } from 'pl-fe/queries/client';
|
||||||
|
|
||||||
|
const appendGroupBlock = (groupId: string, accountId: string) =>
|
||||||
|
queryClient.setQueryData<InfiniteData<ReturnType<typeof minifyAccountList>>>(['accountsLists', 'groupBlocks', groupId], (data) => {
|
||||||
|
if (!data || data.pages.some(page => page.items.includes(accountId))) return data;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...data,
|
||||||
|
pages: data.pages.map((page, index) => index === 0 ? ({ ...page, items: [accountId, ...page.items] }) : page),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const removeGroupBlock = (groupId: string, accountId: string) =>
|
||||||
|
queryClient.setQueryData<InfiniteData<ReturnType<typeof minifyAccountList>>>(['accountsLists', 'groupBlocks', groupId], (data) => data ? {
|
||||||
|
...data,
|
||||||
|
pages: data.pages.map(({ items, ...page }) => ({ ...page, items: items.filter((id) => id !== accountId) })),
|
||||||
|
} : undefined);
|
||||||
|
|
||||||
|
const useGroupBlocks = makePaginatedResponseQuery(
|
||||||
|
(groupId: string) => ['accountsLists', 'groupBlocks', groupId],
|
||||||
|
(client, [groupId]) => client.experimental.groups.getGroupBlocks(groupId).then(minifyAccountList),
|
||||||
|
);
|
||||||
|
|
||||||
|
const useBlockGroupUserMutation = (groupId: string, accountId: string) => {
|
||||||
|
const client = useClient();
|
||||||
|
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: ['accountsLists', 'groupBlocks', groupId, accountId],
|
||||||
|
mutationFn: () => client.experimental.groups.blockGroupUsers(groupId, [accountId]),
|
||||||
|
onSettled: () => appendGroupBlock(groupId, accountId),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const useUnblockGroupUserMutation = (groupId: string, accountId: string) => {
|
||||||
|
const client = useClient();
|
||||||
|
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: ['accountsLists', 'groupBlocks', groupId, accountId],
|
||||||
|
mutationFn: () => client.experimental.groups.unblockGroupUsers(groupId, [accountId]),
|
||||||
|
onSettled: () => removeGroupBlock(groupId, accountId),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
useGroupBlocks,
|
||||||
|
useBlockGroupUserMutation,
|
||||||
|
useUnblockGroupUserMutation,
|
||||||
|
};
|
|
@ -36,7 +36,6 @@ import status_lists from './status-lists';
|
||||||
import statuses from './statuses';
|
import statuses from './statuses';
|
||||||
import tags from './tags';
|
import tags from './tags';
|
||||||
import timelines from './timelines';
|
import timelines from './timelines';
|
||||||
import user_lists from './user-lists';
|
|
||||||
|
|
||||||
const reducers = {
|
const reducers = {
|
||||||
accounts_meta,
|
accounts_meta,
|
||||||
|
@ -72,7 +71,6 @@ const reducers = {
|
||||||
statuses,
|
statuses,
|
||||||
tags,
|
tags,
|
||||||
timelines,
|
timelines,
|
||||||
user_lists,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const appReducer = combineReducers(reducers);
|
const appReducer = combineReducers(reducers);
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
import reducer from './user-lists';
|
|
||||||
|
|
||||||
describe('user_lists reducer', () => {
|
|
||||||
it('should return the initial state', () => {
|
|
||||||
expect(reducer(undefined, {} as any)).toMatchObject({
|
|
||||||
group_blocks: {},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,68 +0,0 @@
|
||||||
import { create } from 'mutative';
|
|
||||||
|
|
||||||
import {
|
|
||||||
GROUP_BLOCKS_FETCH_REQUEST,
|
|
||||||
GROUP_BLOCKS_FETCH_SUCCESS,
|
|
||||||
GROUP_BLOCKS_FETCH_FAIL,
|
|
||||||
GROUP_UNBLOCK_SUCCESS,
|
|
||||||
type GroupsAction,
|
|
||||||
} from 'pl-fe/actions/groups';
|
|
||||||
|
|
||||||
import type { Account, PaginatedResponse } from 'pl-api';
|
|
||||||
|
|
||||||
interface List {
|
|
||||||
next: (() => Promise<PaginatedResponse<Account>>) | null;
|
|
||||||
items: Array<string>;
|
|
||||||
isLoading: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
type NestedListKey = 'group_blocks';
|
|
||||||
|
|
||||||
type State = Record<NestedListKey, Record<string, List>>;
|
|
||||||
|
|
||||||
const initialState: State = {
|
|
||||||
group_blocks: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
type NestedListPath = [NestedListKey, string];
|
|
||||||
|
|
||||||
const normalizeList = (state: State, path: NestedListPath, accounts: Array<Pick<Account, 'id'>>, next: (() => Promise<PaginatedResponse<any>>) | null = null) =>
|
|
||||||
create(state, (draft) => {
|
|
||||||
const list = draft[path[0]][path[1]];
|
|
||||||
const newList = { ...list, next, items: accounts.map(item => item.id), isLoading: false };
|
|
||||||
draft[path[0]][path[1]] = newList;
|
|
||||||
});
|
|
||||||
|
|
||||||
const userLists = (state = initialState, action: GroupsAction): State => {
|
|
||||||
switch (action.type) {
|
|
||||||
case GROUP_BLOCKS_FETCH_SUCCESS:
|
|
||||||
return normalizeList(state, ['group_blocks', action.groupId], action.accounts, action.next);
|
|
||||||
case GROUP_BLOCKS_FETCH_REQUEST:
|
|
||||||
return create(state, (draft) => {
|
|
||||||
draft.group_blocks[action.groupId] = {
|
|
||||||
items: [],
|
|
||||||
next: null,
|
|
||||||
isLoading: true,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
case GROUP_BLOCKS_FETCH_FAIL:
|
|
||||||
return create(state, (draft) => {
|
|
||||||
draft.group_blocks[action.groupId] = {
|
|
||||||
items: [],
|
|
||||||
next: null,
|
|
||||||
isLoading: false,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
case GROUP_UNBLOCK_SUCCESS:
|
|
||||||
return create(state, (draft) => {
|
|
||||||
const list = draft.group_blocks[action.groupId];
|
|
||||||
if (list.items) list.items = list.items.filter(item => item !== action.accountId);
|
|
||||||
});
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export {
|
|
||||||
userLists as default,
|
|
||||||
};
|
|
Loading…
Reference in a new issue