diff --git a/CHANGELOG.md b/CHANGELOG.md index 24db7aecdb805a4336f3fd80fedbfa94a6312c68..085e4981cd23be3b446482520db3238d98ab26a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,7 +24,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Optimistic update for actions in users module and fetching users after api function finished its execution - Relay management - Ability to fetch all statuses from a given instance -- Grouped reports: now you can view reports, which are grouped by status (pagination is not implemented yet, though) - Ability to confirm users' emails and resend confirmation emails - Report notes - Ability to moderate users on the statuses page diff --git a/src/api/__mocks__/reports.js b/src/api/__mocks__/reports.js index ba4e412e5dd3464245801532e458936a21b36e13..36fc20088ae4eb347dea11e4903f30e98b1e2ce3 100644 --- a/src/api/__mocks__/reports.js +++ b/src/api/__mocks__/reports.js @@ -11,40 +11,12 @@ const reports = [ { created_at: '2019-05-18T13:01:33.000Z', account: { acct: 'nick', display_name: 'Nick Keys', tags: [] }, actor: { acct: 'admin' }, state: 'closed', id: '4', content: '', statuses: [] } ] -const groupedReports = [ - { account: { avatar: 'http://localhost:4000/images/avi.png', confirmation_pending: false, deactivated: false, display_name: 'leo', id: '9oG0YghgBi94EATI9I', local: true, nickname: 'leo', roles: { admin: false, moderator: false }, tags: [] }, - actors: [{ acct: 'admin', avatar: 'http://localhost:4000/images/avi.png', deactivated: false, display_name: 'admin', id: '9oFz4pTauG0cnJ581w', local: true, nickname: 'admin', roles: { admin: false, moderator: false }, tags: [], url: 'http://localhost:4000/users/admin', username: 'admin' }], - date: '2019-11-23T12:56:11.969772Z', - reports: [ - { created_at: '2019-05-21T21:35:33.000Z', account: { acct: 'benj', display_name: 'Benjamin Fame', tags: [] }, actor: { acct: 'admin' }, state: 'open', id: '2', content: 'This is a report', statuses: [] }, - { created_at: '2019-05-20T22:45:33.000Z', account: { acct: 'alice', display_name: 'Alice Pool', tags: [] }, actor: { acct: 'admin2' }, state: 'resolved', id: '7', content: 'Please block this user', statuses: [ - { account: { display_name: 'Alice Pool', avatar: '' }, visibility: 'public', sensitive: false, id: '11', content: 'Hey!', url: '', created_at: '2019-05-10T21:35:33.000Z' }, - { account: { display_name: 'Alice Pool', avatar: '' }, visibility: 'unlisted', sensitive: true, id: '10', content: 'Bye!', url: '', created_at: '2019-05-10T21:00:33.000Z' } - ] } - ], - status: { - account: { acct: 'leo' }, - content: 'At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis', - created_at: '2019-11-23T12:55:20.000Z', - id: '9pFoQO69piu7cUDnJg', - url: 'http://localhost:4000/notice/9pFoQO69piu7cUDnJg', - visibility: 'unlisted', - sensitive: true - }, - status_deleted: false - } -] - export async function fetchReports(filter, page, pageSize, authHost, token) { return filter.length > 0 ? Promise.resolve({ data: { reports: reports.filter(report => report.state === filter) }}) : Promise.resolve({ data: { reports }}) } -export async function fetchGroupedReports(authHost, token) { - return Promise.resolve({ data: { reports: groupedReports }}) -} - export async function changeState(reportsData, authHost, token) { return Promise.resolve({ data: '' }) } diff --git a/src/api/reports.js b/src/api/reports.js index 3454da2fb1eb13e9dab8a093473213704b638fc8..abd371c1c5497c0b26f4f58e37f182f57fd67b40 100644 --- a/src/api/reports.js +++ b/src/api/reports.js @@ -24,15 +24,6 @@ export async function fetchReports(filter, page, pageSize, authHost, token) { }) } -export async function fetchGroupedReports(authHost, token) { - return await request({ - baseURL: baseName(authHost), - url: `/api/pleroma/admin/grouped_reports`, - method: 'get', - headers: authHeaders(token) - }) -} - export async function createNote(content, reportID, authHost, token) { return await request({ baseURL: baseName(authHost), diff --git a/src/lang/en.js b/src/lang/en.js index 5130a100c3b2f1ee8834ca8aa7e5f78a1bbb6471..7512ecbf521120e747fd5d6cc646eca554453e05 100644 --- a/src/lang/en.js +++ b/src/lang/en.js @@ -273,7 +273,6 @@ export default { }, reports: { reports: 'Reports', - groupedReports: 'Grouped reports', reply: 'Reply', from: 'From', showNotes: 'Show notes', diff --git a/src/store/modules/reports.js b/src/store/modules/reports.js index c1b07b51241c46b27d6f26693149d36b8b5704bb..3a836a2fe732bef9bc4e55d63cea1029a7432f1e 100644 --- a/src/store/modules/reports.js +++ b/src/store/modules/reports.js @@ -1,13 +1,11 @@ -import { changeState, fetchReports, fetchGroupedReports, createNote, deleteNote } from '@/api/reports' +import { changeState, fetchReports, createNote, deleteNote } from '@/api/reports' const reports = { state: { fetchedReports: [], - fetchedGroupedReports: [], totalReportsCount: 0, currentPage: 1, pageSize: 50, - groupReports: false, stateFilter: '', loading: true }, @@ -24,17 +22,11 @@ const reports = { SET_REPORTS: (state, reports) => { state.fetchedReports = reports }, - SET_GROUPED_REPORTS: (state, reports) => { - state.fetchedGroupedReports = reports - }, SET_REPORTS_COUNT: (state, total) => { state.totalReportsCount = total }, SET_REPORTS_FILTER: (state, filter) => { state.stateFilter = filter - }, - SET_REPORTS_GROUPING: (state) => { - state.groupReports = !state.groupReports } }, actions: { @@ -46,14 +38,7 @@ const reports = { return updatedReportsIds.includes(report.id) ? { ...report, state: reportsData[0].state } : report }) - const updatedGroupedReports = state.fetchedGroupedReports.map(group => { - const updatedReportsIds = reportsData.map(({ id }) => id) - const updatedReports = group.reports.map(report => updatedReportsIds.includes(report.id) ? { ...report, state: reportsData[0].state } : report) - return { ...group, reports: updatedReports } - }) - commit('SET_REPORTS', updatedReports) - commit('SET_GROUPED_REPORTS', updatedGroupedReports) }, ClearFetchedReports({ commit }) { commit('SET_REPORTS', []) @@ -67,19 +52,9 @@ const reports = { commit('SET_PAGE', page) commit('SET_LOADING', false) }, - async FetchGroupedReports({ commit, getters }) { - commit('SET_LOADING', true) - const { data } = await fetchGroupedReports(getters.authHost, getters.token) - - commit('SET_GROUPED_REPORTS', data.reports) - commit('SET_LOADING', false) - }, SetFilter({ commit }, filter) { commit('SET_REPORTS_FILTER', filter) }, - ToggleReportsGrouping({ commit }) { - commit('SET_REPORTS_GROUPING') - }, CreateReportNote({ commit, getters, state, rootState }, { content, reportID }) { createNote(content, reportID, getters.authHost, getters.token) diff --git a/src/store/modules/status.js b/src/store/modules/status.js index 228e03f1331b4f377f812f778c92bd9b76b871e5..81e86dbaf35f21ef30832654905d4db81b550c5a 100644 --- a/src/store/modules/status.js +++ b/src/store/modules/status.js @@ -36,8 +36,6 @@ const status = { dispatch('FetchUserStatuses', { userId, godmode }) } else if (fetchStatusesByInstance) { // called from Statuses by Instance dispatch('FetchStatusesByInstance') - } else { // called from GroupedReports - dispatch('FetchGroupedReports') } }, async DeleteStatus({ dispatch, getters }, { statusId, reportCurrentPage, userId, godmode, fetchStatusesByInstance }) { @@ -48,8 +46,6 @@ const status = { dispatch('FetchUserStatuses', { userId, godmode }) } else if (fetchStatusesByInstance) { // called from Statuses by Instance dispatch('FetchStatusesByInstance') - } else { // called from GroupedReports - dispatch('FetchGroupedReports') } }, async FetchStatusesByInstance({ commit, getters, state }) { diff --git a/src/views/reports/components/GroupedReport.vue b/src/views/reports/components/GroupedReport.vue deleted file mode 100644 index 54ee5b1a0b6d6823849a49c71409084ea6331f61..0000000000000000000000000000000000000000 --- a/src/views/reports/components/GroupedReport.vue +++ /dev/null @@ -1,169 +0,0 @@ -<template> - <el-timeline class="reports-timeline"> - <el-timeline-item - v-for="groupedReport in groupedReports" - :key="groupedReport.id" - :timestamp="parseTimestamp(groupedReport.date)" - placement="top" - class="timeline-item-container"> - <el-card class="grouped-report"> - <div class="header-container"> - <div> - <h3 class="report-title">{{ $t('reports.reportsOn') }} {{ groupedReport.account.display_name }}</h3> - </div> - <div> - <el-dropdown trigger="click"> - <el-button plain size="small" icon="el-icon-edit" class="report-actions-button">{{ $t('reports.changeAllReports') }}<i class="el-icon-arrow-down el-icon--right"/></el-button> - <el-dropdown-menu slot="dropdown"> - <el-dropdown-item @click.native="changeAllReports('resolved', groupedReport.reports)">{{ $t('reports.resolveAll') }}</el-dropdown-item> - <el-dropdown-item @click.native="changeAllReports('open', groupedReport.reports)">{{ $t('reports.reopenAll') }}</el-dropdown-item> - <el-dropdown-item @click.native="changeAllReports('closed', groupedReport.reports)">{{ $t('reports.closeAll') }}</el-dropdown-item> - </el-dropdown-menu> - </el-dropdown> - <moderate-user-dropdown :account="groupedReport.account"/> - </div> - </div> - <div> - <el-divider class="divider"/> - <span class="report-row-key">{{ $t('reports.account') }}:</span> - <img - :src="groupedReport.account.avatar" - alt="avatar" - class="avatar-img"> - <a :href="groupedReport.account.url" target="_blank"> - <span>{{ groupedReport.account.nickname }}</span> - </a> - </div> - <div> - <el-divider class="divider"/> - <span class="report-row-key">{{ $t('reports.actors') }}:</span> - <span v-for="(actor, index) in groupedReport.actors" :key="actor.id"> - <a :href="actor.url" target="_blank"> - {{ actor.acct }}<span v-if="index < groupedReport.actors.length - 1">, </span> - </a> - </span> - </div> - <div v-if="groupedReport.status"> - <el-divider class="divider"/> - <span class="report-row-key">{{ $t('reports.reportedStatus') }}:</span> - <status :status="groupedReport.status" :show-checkbox="false" class="reported-status"/> - </div> - <div v-if="groupedReport.reports"> - <el-collapse> - <el-collapse-item :title="$t('reports.reports')"> - <report-card :reports="groupedReport.reports"/> - </el-collapse-item> - </el-collapse> - </div> - </el-card> - </el-timeline-item> - </el-timeline> -</template> - -<script> -import moment from 'moment' -import ModerateUserDropdown from './ModerateUserDropdown' -import ReportCard from './ReportCard' -import Status from '@/components/Status' - -export default { - name: 'Report', - components: { ModerateUserDropdown, ReportCard, Status }, - props: { - groupedReports: { - type: Array, - required: true - } - }, - methods: { - changeAllReports(reportState, groupOfReports) { - const reportsData = groupOfReports.map(report => { - return { id: report.id, state: reportState } - }) - this.$store.dispatch('ChangeReportState', reportsData) - }, - parseTimestamp(timestamp) { - return moment(timestamp).format('L HH:mm') - } - } -} -</script> - -<style rel='stylesheet/scss' lang='scss'> - a { - text-decoration: underline; - } - .avatar-img { - vertical-align: bottom; - width: 15px; - height: 15px; - margin-left: 5px; - } - .el-card__body { - padding: 17px; - } - .el-card__header { - background-color: #FAFAFA; - padding: 10px 20px; - } - .el-icon-arrow-right { - margin-right: 6px; - } - .divider { - margin: 15px 0; - } - .grouped-report { - .header-container { - display: flex; - justify-content: space-between; - align-items: baseline; - height: 36px; - } - } - .line { - width: 100%; - height: 0; - border: 0.5px solid #EBEEF5; - margin: 15px 0 15px; - } - .report-title { - margin: 0; - } - .report-row-key { - font-size: 14px; - font-weight: 500; - } - .reports-timeline { - margin: 30px 45px 45px 19px; - padding: 0px; - } - .reported-status { - margin-top: 15px; - } - - @media only screen and (max-width:480px) { - .grouped-report { - .header-container { - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: flex-start; - height: auto; - } - .report-actions-button { - margin: 3px 0 6px; - } - .report-title { - margin-bottom: 7px; - } - } - .block { - .reports-timeline .el-timeline { - margin: 20px 10px; - .el-timeline-item__wrapper { - padding-left: 20px; - } - } - } - } -</style> diff --git a/src/views/reports/index.vue b/src/views/reports/index.vue index 8c37e6a1f9ab0f2147e3fb3ba399f0de895212d8..64993da3c457a5472ad179190d1557437d44723f 100644 --- a/src/views/reports/index.vue +++ b/src/views/reports/index.vue @@ -1,22 +1,14 @@ <template> <div class="reports-container"> - <h1 v-if="groupReports"> - {{ $t('reports.groupedReports') }} - <span class="report-count">({{ normalizedReportsCount }})</span> - </h1> - <h1 v-else> + <h1> {{ $t('reports.reports') }} <span class="report-count">({{ normalizedReportsCount }})</span> </h1> <div class="reports-filter-container"> - <reports-filter v-if="!groupReports"/> - <el-checkbox v-model="groupReports" class="group-reports-checkbox"> - Group reports by statuses - </el-checkbox> + <reports-filter/> </div> <div class="block"> - <grouped-report v-loading="loading" v-if="groupReports" :grouped-reports="groupedReports"/> - <report v-loading="loading" v-else :reports="reports"/> + <report v-loading="loading" :reports="reports"/> <div v-if="reports.length === 0" class="no-reports-message"> <p>There are no reports to display</p> </div> @@ -25,32 +17,18 @@ </template> <script> -import GroupedReport from './components/GroupedReport' import numeral from 'numeral' import Report from './components/Report' import ReportsFilter from './components/ReportsFilter' export default { - components: { GroupedReport, Report, ReportsFilter }, + components: { Report, ReportsFilter }, computed: { - groupedReports() { - return this.$store.state.reports.fetchedGroupedReports - }, - groupReports: { - get() { - return this.$store.state.reports.groupReports - }, - set() { - this.toggleReportsGrouping() - } - }, loading() { return this.$store.state.reports.loading }, normalizedReportsCount() { - return this.groupReports - ? numeral(this.$store.state.reports.fetchedGroupedReports.length).format('0a') - : numeral(this.$store.state.reports.totalReportsCount).format('0a') + return numeral(this.$store.state.reports.totalReportsCount).format('0a') }, reports() { return this.$store.state.reports.fetchedReports @@ -58,12 +36,6 @@ export default { }, mounted() { this.$store.dispatch('FetchReports', 1) - this.$store.dispatch('FetchGroupedReports') - }, - methods: { - toggleReportsGrouping() { - this.$store.dispatch('ToggleReportsGrouping') - } } } </script> @@ -77,9 +49,6 @@ export default { margin: 22px 15px 22px 15px; padding-bottom: 0 } - .group-reports-checkbox { - margin-top: 10px; - } h1 { margin: 22px 0 0 15px; } diff --git a/test/views/reports/groupedReport.test.js b/test/views/reports/groupedReport.test.js deleted file mode 100644 index b24d05e45ffaeec29447517c8170f8c9531f7d05..0000000000000000000000000000000000000000 --- a/test/views/reports/groupedReport.test.js +++ /dev/null @@ -1,47 +0,0 @@ -import Vuex from 'vuex' -import { mount, createLocalVue, config } from '@vue/test-utils' -import Element from 'element-ui' -import GroupedReport from '@/views/reports/components/GroupedReport' -import storeConfig from './store.conf' -import { cloneDeep } from 'lodash' -import flushPromises from 'flush-promises' - -config.mocks["$t"] = () => {} - -const localVue = createLocalVue() -localVue.use(Vuex) -localVue.use(Element) - -jest.mock('@/api/reports') - -describe('Grouped report', () => { - let store - - beforeEach(async() => { - store = new Vuex.Store(cloneDeep(storeConfig)) - store.dispatch('FetchGroupedReports') - await flushPromises() - }) - - it('changes state of all reports in a group', async (done) => { - const groupedReports = store.state.reports.fetchedGroupedReports - const wrapper = mount(GroupedReport, { - store, - localVue, - propsData: { - groupedReports - } - }) - - expect(groupedReports[0].reports[0].state).toBe('open') - expect(groupedReports[0].reports[1].state).toBe('resolved') - - const button = wrapper.find(`.grouped-report .el-dropdown-menu__item:nth-child(3)`) - button.trigger('click') - await flushPromises() - - expect(store.state.reports.fetchedGroupedReports[0].reports[0].state).toBe('closed') - expect(store.state.reports.fetchedGroupedReports[0].reports[1].state).toBe('closed') - done() - }) -})