Merge branch 'edit-group' into 'develop'

Edit group

See merge request soapbox-pub/soapbox!2357
environments/review-develop-3zknud/deployments/2912
Alex Gleason 2 years ago
commit bc457b61d1

@ -1,5 +1,6 @@
import { defineMessages } from 'react-intl';
import { deleteEntities } from 'soapbox/entity-store/actions';
import toast from 'soapbox/toast';
import api, { getLinks } from '../api';
@ -191,7 +192,7 @@ const updateGroupFail = (error: AxiosError) => ({
});
const deleteGroup = (id: string) => (dispatch: AppDispatch, getState: () => RootState) => {
dispatch(deleteGroupRequest(id));
dispatch(deleteEntities([id], 'Group'));
return api(getState).delete(`/api/v1/groups/${id}`)
.then(() => dispatch(deleteGroupSuccess(id)))

@ -1,3 +1,8 @@
import { importEntities } from 'soapbox/entity-store/actions';
import { Entities } from 'soapbox/entity-store/entities';
import { Group, groupSchema } from 'soapbox/schemas';
import { filteredArray } from 'soapbox/schemas/utils';
import { getSettings } from '../settings';
import type { AppDispatch, RootState } from 'soapbox/store';
@ -18,11 +23,11 @@ const importAccount = (account: APIEntity) =>
const importAccounts = (accounts: APIEntity[]) =>
({ type: ACCOUNTS_IMPORT, accounts });
const importGroup = (group: APIEntity) =>
({ type: GROUP_IMPORT, group });
const importGroup = (group: Group) =>
importEntities([group], Entities.GROUPS);
const importGroups = (groups: APIEntity[]) =>
({ type: GROUPS_IMPORT, groups });
const importGroups = (groups: Group[]) =>
importEntities(groups, Entities.GROUPS);
const importStatus = (status: APIEntity, idempotencyKey?: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
@ -69,17 +74,8 @@ const importFetchedGroup = (group: APIEntity) =>
importFetchedGroups([group]);
const importFetchedGroups = (groups: APIEntity[]) => {
const normalGroups: APIEntity[] = [];
const processGroup = (group: APIEntity) => {
if (!group.id) return;
normalGroups.push(group);
};
groups.forEach(processGroup);
return importGroups(normalGroups);
const entities = filteredArray(groupSchema).catch([]).parse(groups);
return importGroups(entities);
};
const importFetchedStatus = (status: APIEntity, idempotencyKey?: string) =>

@ -2,6 +2,4 @@ export enum Entities {
GROUPS = 'Groups',
GROUP_RELATIONSHIPS = 'GroupRelationships',
GROUP_MEMBERSHIPS = 'GroupMemberships',
POPULAR_GROUPS = 'PopularGroups',
SUGGESTED_GROUPS = 'SuggestedGroups',
}

@ -98,7 +98,7 @@ describe('<GroupActionButton />', () => {
relationship: buildGroupRelationship({
requested: false,
member: true,
role: 'admin',
role: 'owner',
}),
});
});

@ -27,7 +27,7 @@ const GroupActionButton = ({ group }: IGroupActionButton) => {
const isRequested = group.relationship?.requested;
const isNonMember = !group.relationship?.member && !isRequested;
const isAdmin = group.relationship?.role === 'admin';
const isAdmin = group.relationship?.role === 'owner';
const isBlocked = group.relationship?.blocked_by;
const onJoinGroup = () => joinGroup.mutate(group);

@ -1,12 +1,12 @@
import React, { useCallback, useEffect } from 'react';
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
import { fetchGroup, fetchGroupBlocks, groupUnblock } from 'soapbox/actions/groups';
import { fetchGroupBlocks, groupUnblock } from 'soapbox/actions/groups';
import Account from 'soapbox/components/account';
import ScrollableList from 'soapbox/components/scrollable-list';
import { Button, Column, HStack, Spinner } from 'soapbox/components/ui';
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
import { makeGetAccount, makeGetGroup } from 'soapbox/selectors';
import { useAppDispatch, useAppSelector, useGroup } from 'soapbox/hooks';
import { makeGetAccount } from 'soapbox/selectors';
import toast from 'soapbox/toast';
import ColumnForbidden from '../ui/components/column-forbidden';
@ -62,14 +62,12 @@ const GroupBlockedMembers: React.FC<IGroupBlockedMembers> = ({ params }) => {
const intl = useIntl();
const dispatch = useAppDispatch();
const id = params?.id || '';
const id = params?.id;
const getGroup = useCallback(makeGetGroup(), []);
const group = useAppSelector(state => getGroup(state, id));
const { group } = useGroup(id);
const accountIds = useAppSelector((state) => state.user_lists.group_blocks.get(id)?.items);
useEffect(() => {
if (!group) dispatch(fetchGroup(id));
dispatch(fetchGroupBlocks(id));
}, [id]);
@ -81,7 +79,7 @@ const GroupBlockedMembers: React.FC<IGroupBlockedMembers> = ({ params }) => {
);
}
if (!group.relationship.role || !['admin', 'moderator'].includes(group.relationship.role)) {
if (!group.relationship.role || !['owner', 'admin', 'moderator'].includes(group.relationship.role)) {
return (<ColumnForbidden />);
}

@ -1,12 +1,12 @@
import React, { useCallback, useEffect } from 'react';
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
import { authorizeGroupMembershipRequest, fetchGroup, fetchGroupMembershipRequests, rejectGroupMembershipRequest } from 'soapbox/actions/groups';
import { authorizeGroupMembershipRequest, fetchGroupMembershipRequests, rejectGroupMembershipRequest } from 'soapbox/actions/groups';
import Account from 'soapbox/components/account';
import ScrollableList from 'soapbox/components/scrollable-list';
import { Button, Column, HStack, Spinner } from 'soapbox/components/ui';
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
import { makeGetAccount, makeGetGroup } from 'soapbox/selectors';
import { useAppDispatch, useAppSelector, useGroup } from 'soapbox/hooks';
import { makeGetAccount } from 'soapbox/selectors';
import toast from 'soapbox/toast';
import ColumnForbidden from '../ui/components/column-forbidden';
@ -77,14 +77,12 @@ const GroupMembershipRequests: React.FC<IGroupMembershipRequests> = ({ params })
const intl = useIntl();
const dispatch = useAppDispatch();
const id = params?.id || '';
const id = params?.id;
const getGroup = useCallback(makeGetGroup(), []);
const group = useAppSelector(state => getGroup(state, id));
const { group } = useGroup(id);
const accountIds = useAppSelector((state) => state.user_lists.membership_requests.get(id)?.items);
useEffect(() => {
if (!group) dispatch(fetchGroup(id));
dispatch(fetchGroupMembershipRequests(id));
}, [id]);
@ -96,7 +94,7 @@ const GroupMembershipRequests: React.FC<IGroupMembershipRequests> = ({ params })
);
}
if (!group.relationship.role || !['admin', 'moderator'].includes(group.relationship.role)) {
if (!group.relationship.role || !['owner', 'admin', 'moderator'].includes(group.relationship.role)) {
return (<ColumnForbidden />);
}

@ -1,13 +1,12 @@
import React, { useCallback, useEffect } from 'react';
import React from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { useHistory } from 'react-router-dom';
import { deleteGroup, editGroup, fetchGroup } from 'soapbox/actions/groups';
import { deleteGroup, editGroup } from 'soapbox/actions/groups';
import { openModal } from 'soapbox/actions/modals';
import List, { ListItem } from 'soapbox/components/list';
import { CardBody, Column, Spinner } from 'soapbox/components/ui';
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
import { makeGetGroup } from 'soapbox/selectors';
import { useAppDispatch, useGroup } from 'soapbox/hooks';
import ColumnForbidden from '../ui/components/column-forbidden';
@ -29,18 +28,12 @@ interface IManageGroup {
}
const ManageGroup: React.FC<IManageGroup> = ({ params }) => {
const history = useHistory();
const { id } = params;
const intl = useIntl();
const history = useHistory();
const dispatch = useAppDispatch();
const id = params?.id || '';
const getGroup = useCallback(makeGetGroup(), []);
const group = useAppSelector(state => getGroup(state, id));
useEffect(() => {
if (!group) dispatch(fetchGroup(id));
}, [id]);
const { group } = useGroup(id);
if (!group || !group.relationship) {
return (
@ -50,7 +43,7 @@ const ManageGroup: React.FC<IManageGroup> = ({ params }) => {
);
}
if (!group.relationship.role || !['admin', 'moderator'].includes(group.relationship.role)) {
if (!group.relationship.role || !['owner', 'admin', 'moderator'].includes(group.relationship.role)) {
return (<ColumnForbidden />);
}
@ -72,7 +65,7 @@ const ManageGroup: React.FC<IManageGroup> = ({ params }) => {
return (
<Column label={intl.formatMessage(messages.heading)} backHref={`/groups/${id}`}>
<CardBody className='space-y-4'>
{group.relationship.role === 'admin' && (
{group.relationship.role === 'owner' && (
<List>
<ListItem label={intl.formatMessage(messages.editGroup)} onClick={onEditGroup}>
<span dangerouslySetInnerHTML={{ __html: group.display_name_html }} />
@ -83,7 +76,7 @@ const ManageGroup: React.FC<IManageGroup> = ({ params }) => {
<ListItem label={intl.formatMessage(messages.pendingRequests)} onClick={navigateToPending} />
<ListItem label={intl.formatMessage(messages.blockedMembers)} onClick={navigateToBlocks} />
</List>
{group.relationship.role === 'admin' && (
{group.relationship.role === 'owner' && (
<List>
<ListItem label={intl.formatMessage(messages.deleteGroup)} onClick={onDeleteGroup} />
</List>

@ -9,7 +9,7 @@ function usePopularGroups() {
const features = useFeatures();
const { entities, ...result } = useEntities<Group>(
[Entities.POPULAR_GROUPS, ''],
[Entities.GROUPS, 'popular'],
'/api/mock/groups', // '/api/v1/truth/trends/groups'
{
schema: groupSchema,

@ -9,7 +9,7 @@ function useSuggestedGroups() {
const features = useFeatures();
const { entities, ...result } = useEntities<Group>(
[Entities.SUGGESTED_GROUPS, ''],
[Entities.GROUPS, 'suggested'],
'/api/mock/groups', // '/api/v1/truth/suggestions/groups'
{
schema: groupSchema,

Loading…
Cancel
Save