Rework admin approve/reject actions
This commit is contained in:
parent
cdc8c70078
commit
0e846784df
|
@ -39,6 +39,10 @@ const ADMIN_USERS_APPROVE_REQUEST = 'ADMIN_USERS_APPROVE_REQUEST';
|
|||
const ADMIN_USERS_APPROVE_SUCCESS = 'ADMIN_USERS_APPROVE_SUCCESS';
|
||||
const ADMIN_USERS_APPROVE_FAIL = 'ADMIN_USERS_APPROVE_FAIL';
|
||||
|
||||
const ADMIN_USERS_REJECT_REQUEST = 'ADMIN_USERS_REJECT_REQUEST';
|
||||
const ADMIN_USERS_REJECT_SUCCESS = 'ADMIN_USERS_REJECT_SUCCESS';
|
||||
const ADMIN_USERS_REJECT_FAIL = 'ADMIN_USERS_REJECT_FAIL';
|
||||
|
||||
const ADMIN_USERS_DEACTIVATE_REQUEST = 'ADMIN_USERS_DEACTIVATE_REQUEST';
|
||||
const ADMIN_USERS_DEACTIVATE_SUCCESS = 'ADMIN_USERS_DEACTIVATE_SUCCESS';
|
||||
const ADMIN_USERS_DEACTIVATE_FAIL = 'ADMIN_USERS_DEACTIVATE_FAIL';
|
||||
|
@ -309,56 +313,80 @@ const deactivateUsers = (accountIds: string[], reportId?: string) =>
|
|||
}
|
||||
};
|
||||
|
||||
const deleteUsers = (accountIds: string[]) =>
|
||||
const deleteUser = (accountId: string) =>
|
||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
||||
const nicknames = accountIdsToAccts(getState(), accountIds);
|
||||
dispatch({ type: ADMIN_USERS_DELETE_REQUEST, accountIds });
|
||||
const nicknames = accountIdsToAccts(getState(), [accountId]);
|
||||
dispatch({ type: ADMIN_USERS_DELETE_REQUEST, accountId });
|
||||
return api(getState)
|
||||
.delete('/api/v1/pleroma/admin/users', { data: { nicknames } })
|
||||
.then(({ data: nicknames }) => {
|
||||
dispatch({ type: ADMIN_USERS_DELETE_SUCCESS, nicknames, accountIds });
|
||||
dispatch({ type: ADMIN_USERS_DELETE_SUCCESS, nicknames, accountId });
|
||||
}).catch(error => {
|
||||
dispatch({ type: ADMIN_USERS_DELETE_FAIL, error, accountIds });
|
||||
dispatch({ type: ADMIN_USERS_DELETE_FAIL, error, accountId });
|
||||
});
|
||||
};
|
||||
|
||||
const approveMastodonUsers = (accountIds: string[]) =>
|
||||
const approveMastodonUser = (accountId: string) =>
|
||||
(dispatch: AppDispatch, getState: () => RootState) =>
|
||||
Promise.all(accountIds.map(accountId => {
|
||||
api(getState)
|
||||
.post(`/api/v1/admin/accounts/${accountId}/approve`)
|
||||
.then(({ data: user }) => {
|
||||
dispatch({ type: ADMIN_USERS_APPROVE_SUCCESS, users: [user], accountIds: [accountId] });
|
||||
}).catch(error => {
|
||||
dispatch({ type: ADMIN_USERS_APPROVE_FAIL, error, accountIds: [accountId] });
|
||||
});
|
||||
}));
|
||||
api(getState)
|
||||
.post(`/api/v1/admin/accounts/${accountId}/approve`)
|
||||
.then(({ data: user }) => {
|
||||
dispatch({ type: ADMIN_USERS_APPROVE_SUCCESS, user, accountId });
|
||||
}).catch(error => {
|
||||
dispatch({ type: ADMIN_USERS_APPROVE_FAIL, error, accountId });
|
||||
});
|
||||
|
||||
const approvePleromaUsers = (accountIds: string[]) =>
|
||||
const approvePleromaUser = (accountId: string) =>
|
||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
||||
const nicknames = accountIdsToAccts(getState(), accountIds);
|
||||
const nicknames = accountIdsToAccts(getState(), [accountId]);
|
||||
return api(getState)
|
||||
.patch('/api/v1/pleroma/admin/users/approve', { nicknames })
|
||||
.then(({ data: { users } }) => {
|
||||
dispatch({ type: ADMIN_USERS_APPROVE_SUCCESS, users, accountIds });
|
||||
dispatch({ type: ADMIN_USERS_APPROVE_SUCCESS, user: users[0], accountId });
|
||||
}).catch(error => {
|
||||
dispatch({ type: ADMIN_USERS_APPROVE_FAIL, error, accountIds });
|
||||
dispatch({ type: ADMIN_USERS_APPROVE_FAIL, error, accountId });
|
||||
});
|
||||
};
|
||||
|
||||
const approveUsers = (accountIds: string[]) =>
|
||||
const rejectMastodonUser = (accountId: string) =>
|
||||
(dispatch: AppDispatch, getState: () => RootState) =>
|
||||
api(getState)
|
||||
.post(`/api/v1/admin/accounts/${accountId}/reject`)
|
||||
.then(({ data: user }) => {
|
||||
dispatch({ type: ADMIN_USERS_REJECT_SUCCESS, user, accountId });
|
||||
}).catch(error => {
|
||||
dispatch({ type: ADMIN_USERS_REJECT_FAIL, error, accountId });
|
||||
});
|
||||
|
||||
const approveUser = (accountId: string) =>
|
||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
||||
const state = getState();
|
||||
|
||||
const instance = state.instance;
|
||||
const features = getFeatures(instance);
|
||||
|
||||
dispatch({ type: ADMIN_USERS_APPROVE_REQUEST, accountIds });
|
||||
dispatch({ type: ADMIN_USERS_APPROVE_REQUEST, accountId });
|
||||
|
||||
if (features.mastodonAdmin) {
|
||||
return dispatch(approveMastodonUsers(accountIds));
|
||||
return dispatch(approveMastodonUser(accountId));
|
||||
} else {
|
||||
return dispatch(approvePleromaUsers(accountIds));
|
||||
return dispatch(approvePleromaUser(accountId));
|
||||
}
|
||||
};
|
||||
|
||||
const rejectUser = (accountId: string) =>
|
||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
||||
const state = getState();
|
||||
|
||||
const instance = state.instance;
|
||||
const features = getFeatures(instance);
|
||||
|
||||
dispatch({ type: ADMIN_USERS_REJECT_REQUEST, accountId });
|
||||
|
||||
if (features.mastodonAdmin) {
|
||||
return dispatch(rejectMastodonUser(accountId));
|
||||
} else {
|
||||
return dispatch(deleteUser(accountId));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -562,6 +590,9 @@ export {
|
|||
ADMIN_USERS_APPROVE_REQUEST,
|
||||
ADMIN_USERS_APPROVE_SUCCESS,
|
||||
ADMIN_USERS_APPROVE_FAIL,
|
||||
ADMIN_USERS_REJECT_REQUEST,
|
||||
ADMIN_USERS_REJECT_SUCCESS,
|
||||
ADMIN_USERS_REJECT_FAIL,
|
||||
ADMIN_USERS_DEACTIVATE_REQUEST,
|
||||
ADMIN_USERS_DEACTIVATE_SUCCESS,
|
||||
ADMIN_USERS_DEACTIVATE_FAIL,
|
||||
|
@ -597,8 +628,9 @@ export {
|
|||
closeReports,
|
||||
fetchUsers,
|
||||
deactivateUsers,
|
||||
deleteUsers,
|
||||
approveUsers,
|
||||
deleteUser,
|
||||
approveUser,
|
||||
rejectUser,
|
||||
deleteStatus,
|
||||
toggleStatusSensitivity,
|
||||
tagUsers,
|
||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import { defineMessages, IntlShape } from 'react-intl';
|
||||
|
||||
import { fetchAccountByUsername } from 'soapbox/actions/accounts';
|
||||
import { deactivateUsers, deleteUsers, deleteStatus, toggleStatusSensitivity } from 'soapbox/actions/admin';
|
||||
import { deactivateUsers, deleteUser, deleteStatus, toggleStatusSensitivity } from 'soapbox/actions/admin';
|
||||
import { openModal } from 'soapbox/actions/modals';
|
||||
import OutlineBox from 'soapbox/components/outline-box';
|
||||
import { Stack, Text } from 'soapbox/components/ui';
|
||||
|
@ -102,7 +102,7 @@ const deleteUserModal = (intl: IntlShape, accountId: string, afterConfirm = () =
|
|||
confirm,
|
||||
checkbox,
|
||||
onConfirm: () => {
|
||||
dispatch(deleteUsers([accountId])).then(() => {
|
||||
dispatch(deleteUser(accountId)).then(() => {
|
||||
const message = intl.formatMessage(messages.userDeleted, { acct });
|
||||
dispatch(fetchAccountByUsername(acct));
|
||||
toast.success(message);
|
||||
|
|
|
@ -71,6 +71,7 @@ const ProfilePopper: React.FC<IProfilePopper> = ({ condition, wrapper, children
|
|||
};
|
||||
|
||||
export interface IAccount {
|
||||
acct?: string;
|
||||
account: AccountSchema;
|
||||
action?: React.ReactElement;
|
||||
actionAlignment?: 'center' | 'top';
|
||||
|
@ -99,6 +100,7 @@ export interface IAccount {
|
|||
}
|
||||
|
||||
const Account = ({
|
||||
acct,
|
||||
account,
|
||||
actionType,
|
||||
action,
|
||||
|
@ -228,7 +230,7 @@ const Account = ({
|
|||
|
||||
<Stack space={withAccountNote || note ? 1 : 0}>
|
||||
<HStack alignItems='center' space={1}>
|
||||
<Text theme='muted' size='sm' direction='ltr' truncate>@{username}</Text>
|
||||
<Text theme='muted' size='sm' direction='ltr' truncate>@{acct ?? username}</Text>
|
||||
|
||||
{account.pleroma?.favicon && (
|
||||
<InstanceFavicon account={account} disabled={!withLinkToProfile} />
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
|
||||
import { approveUsers, deleteUsers } from 'soapbox/actions/admin';
|
||||
import { approveUser, rejectUser } from 'soapbox/actions/admin';
|
||||
import { useAccount } from 'soapbox/api/hooks';
|
||||
import Account from 'soapbox/components/account';
|
||||
import { AuthorizeRejectButtons } from 'soapbox/components/authorize-reject-buttons';
|
||||
|
@ -14,18 +14,19 @@ interface IUnapprovedAccount {
|
|||
const UnapprovedAccount: React.FC<IUnapprovedAccount> = ({ accountId }) => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const { account } = useAccount(accountId);
|
||||
const adminAccount = useAppSelector(state => state.admin.users.get(accountId));
|
||||
const { account } = useAccount(adminAccount?.account || undefined);
|
||||
|
||||
if (!account) return null;
|
||||
if (!adminAccount || !account) return null;
|
||||
|
||||
const handleApprove = () => dispatch(approveUsers([account.id]));
|
||||
const handleReject = () => dispatch(deleteUsers([account.id]));
|
||||
const handleApprove = () => dispatch(approveUser(adminAccount.id));
|
||||
const handleReject = () => dispatch(rejectUser(adminAccount.id));
|
||||
|
||||
return (
|
||||
<Account
|
||||
key={account.id}
|
||||
key={adminAccount.id}
|
||||
account={account}
|
||||
acct={`${adminAccount.username}@${adminAccount.domain}`}
|
||||
note={adminAccount?.invite_request || ''}
|
||||
action={(
|
||||
<AuthorizeRejectButtons
|
||||
|
|
|
@ -19,6 +19,8 @@ import {
|
|||
ADMIN_USERS_DELETE_SUCCESS,
|
||||
ADMIN_USERS_APPROVE_REQUEST,
|
||||
ADMIN_USERS_APPROVE_SUCCESS,
|
||||
ADMIN_USERS_REJECT_REQUEST,
|
||||
ADMIN_USERS_REJECT_SUCCESS,
|
||||
} from 'soapbox/actions/admin';
|
||||
import { normalizeAdminReport, normalizeAdminAccount } from 'soapbox/normalizers';
|
||||
import { normalizeId } from 'soapbox/utils/normalizers';
|
||||
|
@ -120,22 +122,18 @@ function importUsers(state: State, users: APIUser[], filters: Filter[], page: nu
|
|||
});
|
||||
}
|
||||
|
||||
function deleteUsers(state: State, accountIds: string[]): State {
|
||||
function deleteUser(state: State, accountId: string): State {
|
||||
return state.withMutations(state => {
|
||||
accountIds.forEach(id => {
|
||||
state.update('awaitingApproval', orderedSet => orderedSet.delete(id));
|
||||
state.deleteIn(['users', id]);
|
||||
});
|
||||
state.update('awaitingApproval', orderedSet => orderedSet.delete(accountId));
|
||||
state.deleteIn(['users', accountId]);
|
||||
});
|
||||
}
|
||||
|
||||
function approveUsers(state: State, users: APIUser[]): State {
|
||||
function approveUser(state: State, user: APIUser): State {
|
||||
const normalizedUser = fixUser(user);
|
||||
return state.withMutations(state => {
|
||||
users.forEach(user => {
|
||||
const normalizedUser = fixUser(user);
|
||||
state.update('awaitingApproval', orderedSet => orderedSet.delete(user.id));
|
||||
state.setIn(['users', user.id], normalizedUser);
|
||||
});
|
||||
state.update('awaitingApproval', orderedSet => orderedSet.delete(user.id));
|
||||
state.setIn(['users', user.id], normalizedUser);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -207,11 +205,13 @@ export default function admin(state: State = ReducerRecord(), action: AnyAction)
|
|||
return importUsers(state, action.users, action.filters, action.page);
|
||||
case ADMIN_USERS_DELETE_REQUEST:
|
||||
case ADMIN_USERS_DELETE_SUCCESS:
|
||||
return deleteUsers(state, action.accountIds);
|
||||
case ADMIN_USERS_REJECT_REQUEST:
|
||||
case ADMIN_USERS_REJECT_SUCCESS:
|
||||
return deleteUser(state, action.accountId);
|
||||
case ADMIN_USERS_APPROVE_REQUEST:
|
||||
return state.update('awaitingApproval', set => set.subtract(action.accountIds));
|
||||
return state.update('awaitingApproval', set => set.remove(action.accountId));
|
||||
case ADMIN_USERS_APPROVE_SUCCESS:
|
||||
return approveUsers(state, action.users);
|
||||
return approveUser(state, action.user);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue