diff --git a/app/soapbox/actions/admin.js b/app/soapbox/actions/admin.js index ce1cab0f6..19bc283e0 100644 --- a/app/soapbox/actions/admin.js +++ b/app/soapbox/actions/admin.js @@ -4,6 +4,10 @@ export const ADMIN_CONFIG_UPDATE_REQUEST = 'ADMIN_CONFIG_UPDATE_REQUEST'; export const ADMIN_CONFIG_UPDATE_SUCCESS = 'ADMIN_CONFIG_UPDATE_SUCCESS'; export const ADMIN_CONFIG_UPDATE_FAIL = 'ADMIN_CONFIG_UPDATE_FAIL'; +export const ADMIN_REPORTS_FETCH_REQUEST = 'ADMIN_REPORTS_FETCH_REQUEST'; +export const ADMIN_REPORTS_FETCH_SUCCESS = 'ADMIN_REPORTS_FETCH_SUCCESS'; +export const ADMIN_REPORTS_FETCH_FAIL = 'ADMIN_REPORTS_FETCH_FAIL'; + export function updateAdminConfig(params) { return (dispatch, getState) => { dispatch({ type: ADMIN_CONFIG_UPDATE_REQUEST }); @@ -16,3 +20,16 @@ export function updateAdminConfig(params) { }); }; } + +export function fetchReports(params) { + return (dispatch, getState) => { + dispatch({ type: ADMIN_REPORTS_FETCH_REQUEST, params }); + return api(getState) + .get('/api/pleroma/admin/reports', params) + .then(({ data }) => { + dispatch({ type: ADMIN_REPORTS_FETCH_SUCCESS, data, params }); + }).catch(error => { + dispatch({ type: ADMIN_REPORTS_FETCH_FAIL, error, params }); + }); + }; +} diff --git a/app/soapbox/features/ui/components/reports_counter_icon.js b/app/soapbox/features/ui/components/reports_counter_icon.js new file mode 100644 index 000000000..82d276791 --- /dev/null +++ b/app/soapbox/features/ui/components/reports_counter_icon.js @@ -0,0 +1,9 @@ +import { connect } from 'react-redux'; +import IconWithBadge from 'soapbox/components/icon_with_badge'; + +const mapStateToProps = state => ({ + count: state.getIn(['admin', 'report_count']), + id: 'gavel', +}); + +export default connect(mapStateToProps)(IconWithBadge); diff --git a/app/soapbox/features/ui/components/tabs_bar.js b/app/soapbox/features/ui/components/tabs_bar.js index 1772b363f..c394c488a 100644 --- a/app/soapbox/features/ui/components/tabs_bar.js +++ b/app/soapbox/features/ui/components/tabs_bar.js @@ -6,6 +6,7 @@ import { FormattedMessage, injectIntl, defineMessages } from 'react-intl'; import { connect } from 'react-redux'; import classNames from 'classnames'; import NotificationsCounterIcon from './notifications_counter_icon'; +import ReportsCounterIcon from './reports_counter_icon'; import SearchContainer from 'soapbox/features/compose/containers/search_container'; import Avatar from '../../../components/avatar'; import ActionBar from 'soapbox/features/compose/components/action_bar'; @@ -14,6 +15,7 @@ import { openSidebar } from '../../../actions/sidebar'; import Icon from '../../../components/icon'; import ThemeToggle from '../../ui/components/theme_toggle'; import { getSoapboxConfig } from 'soapbox/actions/soapbox'; +import { isStaff } from 'soapbox/utils/accounts'; const messages = defineMessages({ post: { id: 'tabs_bar.post', defaultMessage: 'Post' }, @@ -66,6 +68,14 @@ class TabsBar extends React.PureComponent { ); } + if (account && isStaff(account)) { + links.push( + + + + + ); + } links.push( diff --git a/app/soapbox/features/ui/index.js b/app/soapbox/features/ui/index.js index dbc4ac464..cc6af220d 100644 --- a/app/soapbox/features/ui/index.js +++ b/app/soapbox/features/ui/index.js @@ -16,6 +16,7 @@ import { debounce } from 'lodash'; import { uploadCompose, resetCompose } from '../../actions/compose'; import { expandHomeTimeline } from '../../actions/timelines'; import { expandNotifications } from '../../actions/notifications'; +import { fetchReports } from '../../actions/admin'; import { fetchFilters } from '../../actions/filters'; import { clearHeight } from '../../actions/height_cache'; import { openModal } from '../../actions/modal'; @@ -420,6 +421,7 @@ class UI extends React.PureComponent { this.props.dispatch(expandHomeTimeline()); this.props.dispatch(expandNotifications()); // this.props.dispatch(fetchGroups('member')); + this.props.dispatch(fetchReports()); setTimeout(() => this.props.dispatch(fetchFilters()), 500); } diff --git a/app/soapbox/reducers/__tests__/admin-test.js b/app/soapbox/reducers/__tests__/admin-test.js new file mode 100644 index 000000000..e3f0fa370 --- /dev/null +++ b/app/soapbox/reducers/__tests__/admin-test.js @@ -0,0 +1,11 @@ +import reducer from '../admin'; +import { fromJS } from 'immutable'; + +describe('admin reducer', () => { + it('should return the initial state', () => { + expect(reducer(undefined, {})).toEqual(fromJS({ + reports: [], + report_count: 0, + })); + }); +}); diff --git a/app/soapbox/reducers/admin.js b/app/soapbox/reducers/admin.js new file mode 100644 index 000000000..404d5187b --- /dev/null +++ b/app/soapbox/reducers/admin.js @@ -0,0 +1,17 @@ +import { ADMIN_REPORTS_FETCH_SUCCESS } from '../actions/admin'; +import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable'; + +const initialState = ImmutableMap({ + reports: ImmutableList(), + report_count: 0, +}); + +export default function admin(state = initialState, action) { + switch(action.type) { + case ADMIN_REPORTS_FETCH_SUCCESS: + return state.set('reports', fromJS(action.data.reports)) + .set('report_count', action.data.total); + default: + return state; + } +}; diff --git a/app/soapbox/reducers/index.js b/app/soapbox/reducers/index.js index c91f2f0cb..7a8219522 100644 --- a/app/soapbox/reducers/index.js +++ b/app/soapbox/reducers/index.js @@ -42,6 +42,7 @@ import soapbox from './soapbox'; import instance from './instance'; import me from './me'; import auth from './auth'; +import admin from './admin'; const reducers = { dropdown_menu, @@ -87,6 +88,7 @@ const reducers = { instance, me, auth, + admin, }; export default combineReducers(reducers);