From a89ea524a9cb551b5ef11f455c59729f364da496 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 13 Jul 2021 17:59:55 -0500 Subject: [PATCH] Refactor AwaitingApproval --- .../features/admin/awaiting_approval.js | 62 ++++----------- .../admin/components/unapproved_account.js | 77 +++++++++++++++++++ app/soapbox/features/admin/user_index.js | 4 +- app/soapbox/reducers/admin.js | 7 +- app/soapbox/selectors/index.js | 5 +- 5 files changed, 104 insertions(+), 51 deletions(-) create mode 100644 app/soapbox/features/admin/components/unapproved_account.js diff --git a/app/soapbox/features/admin/awaiting_approval.js b/app/soapbox/features/admin/awaiting_approval.js index 4070c8a35..0d95fa685 100644 --- a/app/soapbox/features/admin/awaiting_approval.js +++ b/app/soapbox/features/admin/awaiting_approval.js @@ -5,24 +5,18 @@ import ImmutablePureComponent from 'react-immutable-pure-component'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import Column from '../ui/components/column'; -import IconButton from 'soapbox/components/icon_button'; import ScrollableList from 'soapbox/components/scrollable_list'; -import { fetchUsers, deleteUsers, approveUsers } from 'soapbox/actions/admin'; -import snackbar from 'soapbox/actions/snackbar'; +import UnapprovedAccount from './components/unapproved_account'; +import { fetchUsers } from 'soapbox/actions/admin'; const messages = defineMessages({ heading: { id: 'column.admin.awaiting_approval', defaultMessage: 'Awaiting Approval' }, emptyMessage: { id: 'admin.awaiting_approval.empty_message', defaultMessage: 'There is nobody waiting for approval. When a new user signs up, you can review them here.' }, - approved: { id: 'admin.awaiting_approval.approved_message', defaultMessage: '{acct} was approved!' }, - rejected: { id: 'admin.awaiting_approval.rejected_message', defaultMessage: '{acct} was rejected.' }, }); -const mapStateToProps = state => { - const nicknames = state.getIn(['admin', 'awaitingApproval']); - return { - users: nicknames.toList().map(nickname => state.getIn(['admin', 'users', nickname])), - }; -}; +const mapStateToProps = state => ({ + accountIds: state.getIn(['admin', 'awaitingApproval']), +}); export default @connect(mapStateToProps) @injectIntl @@ -30,7 +24,7 @@ class AwaitingApproval extends ImmutablePureComponent { static propTypes = { intl: PropTypes.object.isRequired, - users: ImmutablePropTypes.list.isRequired, + accountIds: ImmutablePropTypes.orderedSet.isRequired, }; state = { @@ -44,45 +38,21 @@ class AwaitingApproval extends ImmutablePureComponent { .catch(() => {}); } - handleApprove = nickname => { - const { dispatch, intl } = this.props; - return e => { - dispatch(approveUsers([nickname])).then(() => { - const message = intl.formatMessage(messages.approved, { acct: `@${nickname}` }); - dispatch(snackbar.success(message)); - }).catch(() => {}); - }; - } - - handleReject = nickname => { - const { dispatch, intl } = this.props; - return e => { - dispatch(deleteUsers([nickname])).then(() => { - const message = intl.formatMessage(messages.rejected, { acct: `@${nickname}` }); - dispatch(snackbar.info(message)); - }).catch(() => {}); - }; - } - render() { - const { intl, users } = this.props; + const { intl, accountIds } = this.props; const { isLoading } = this.state; - const showLoading = isLoading && users.count() === 0; + const showLoading = isLoading && accountIds.count() === 0; return ( - - {users.map((user, i) => ( -
-
-
@{user.get('nickname')}
-
{user.get('registration_reason')}
-
-
- - -
-
+ + {accountIds.map(id => ( + ))}
diff --git a/app/soapbox/features/admin/components/unapproved_account.js b/app/soapbox/features/admin/components/unapproved_account.js new file mode 100644 index 000000000..578a55c0c --- /dev/null +++ b/app/soapbox/features/admin/components/unapproved_account.js @@ -0,0 +1,77 @@ +import React from 'react'; +import { defineMessages, injectIntl } from 'react-intl'; +import { connect } from 'react-redux'; +import ImmutablePureComponent from 'react-immutable-pure-component'; +import PropTypes from 'prop-types'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import IconButton from 'soapbox/components/icon_button'; +import { deleteUsers, approveUsers } from 'soapbox/actions/admin'; +import { makeGetAccount } from 'soapbox/selectors'; +import snackbar from 'soapbox/actions/snackbar'; + +const messages = defineMessages({ + approved: { id: 'admin.awaiting_approval.approved_message', defaultMessage: '{acct} was approved!' }, + rejected: { id: 'admin.awaiting_approval.rejected_message', defaultMessage: '{acct} was rejected.' }, +}); + +const makeMapStateToProps = () => { + const getAccount = makeGetAccount(); + + const mapStateToProps = (state, { accountId }) => { + return { + account: getAccount(state, accountId), + }; + }; + + return mapStateToProps; +}; + +export default @connect(makeMapStateToProps) +@injectIntl +class UnapprovedAccount extends ImmutablePureComponent { + + static propTypes = { + intl: PropTypes.object.isRequired, + account: ImmutablePropTypes.map.isRequired, + }; + + handleApprove = () => { + const { dispatch, intl, account } = this.props; + + dispatch(approveUsers([account.get('id')])) + .then(() => { + const message = intl.formatMessage(messages.approved, { acct: `@${account.get('acct')}` }); + dispatch(snackbar.success(message)); + }) + .catch(() => {}); + } + + handleReject = () => { + const { dispatch, intl, account } = this.props; + + dispatch(deleteUsers([account.get('id')])) + .then(() => { + const message = intl.formatMessage(messages.rejected, { acct: `@${account.get('acct')}` }); + dispatch(snackbar.info(message)); + }) + .catch(() => {}); + } + + render() { + const { account } = this.props; + + return ( +
+
+
@{account.get('acct')}
+
{account.getIn(['pleroma', 'admin', 'registration_reason'])}
+
+
+ + +
+
+ ); + } + +} diff --git a/app/soapbox/features/admin/user_index.js b/app/soapbox/features/admin/user_index.js index 7d8fc4d3d..4820ba815 100644 --- a/app/soapbox/features/admin/user_index.js +++ b/app/soapbox/features/admin/user_index.js @@ -33,8 +33,8 @@ class UserIndex extends ImmutablePureComponent { } fetchNextPage = () => { - const nextPage = this.state.page + 1; - const filters = this.state.filters.toJS(); + const { filters, page } = this.state; + const nextPage = page + 1; this.props.dispatch(fetchUsers(filters, nextPage)) .then(({ users, count }) => { diff --git a/app/soapbox/reducers/admin.js b/app/soapbox/reducers/admin.js index 58e8e354e..ebd009ed9 100644 --- a/app/soapbox/reducers/admin.js +++ b/app/soapbox/reducers/admin.js @@ -31,9 +31,12 @@ function importUsers(state, users) { users.forEach(user => { user = normalizePleromaUserFields(user); if (!user.is_approved) { - state.update('awaitingApproval', orderedSet => orderedSet.add(user.nickname)); + state.update('awaitingApproval', orderedSet => orderedSet.add(user.id)); } - state.setIn(['users', user.nickname], fromJS(user)); + state.setIn(['users', user.id], ImmutableMap({ + email: user.email, + registration_reason: user.registration_reason, + })); }); }); } diff --git a/app/soapbox/selectors/index.js b/app/soapbox/selectors/index.js index 0615db229..9b222921e 100644 --- a/app/soapbox/selectors/index.js +++ b/app/soapbox/selectors/index.js @@ -5,6 +5,7 @@ const getAccountBase = (state, id) => state.getIn(['accounts', id], null const getAccountCounters = (state, id) => state.getIn(['accounts_counters', id], null); const getAccountRelationship = (state, id) => state.getIn(['relationships', id], null); const getAccountMoved = (state, id) => state.getIn(['accounts', state.getIn(['accounts', id, 'moved'])]); +const getAccountAdminData = (state, id) => state.getIn(['admin', 'users', id]); const getAccountPatron = (state, id) => { const url = state.getIn(['accounts', id, 'url']); return state.getIn(['patron', 'accounts', url]); @@ -16,8 +17,9 @@ export const makeGetAccount = () => { getAccountCounters, getAccountRelationship, getAccountMoved, + getAccountAdminData, getAccountPatron, - ], (base, counters, relationship, moved, patron) => { + ], (base, counters, relationship, moved, admin, patron) => { if (base === null) { return null; } @@ -26,6 +28,7 @@ export const makeGetAccount = () => { map.set('relationship', relationship); map.set('moved', moved); map.set('patron', patron); + map.setIn(['pleroma', 'admin'], admin); }); }); };