forked from AkkomaGang/admin-fe
Merge branch 'feature/remove-grouped-reports' into 'develop'
Remove grouped reports See merge request pleroma/admin-fe!98
This commit is contained in:
commit
5293260870
10 changed files with 24 additions and 336 deletions
31
CHANGELOG.md
31
CHANGELOG.md
|
@ -4,33 +4,31 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
## Unreleased
|
## [2.0] - 2020-02-27
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- **breaking** PleromaFE login feature relies on `admin` scope presence in PleromaFE token (older versions of PleromaFE don't support it)
|
|
||||||
- Moves emoji pack configuration from the main menu to settings tab, redesigns it and fixes bugs
|
|
||||||
- `mailerEnabled` must be set to `true` in order to require password reset (password reset currently only works via email)
|
|
||||||
- Remove fetching initial data for configuring server settings
|
|
||||||
- Actions in users module (ActivateUsers, AddRight, DeactivateUsers, DeleteRight, DeleteUsers) now accept an array of users instead of one user
|
|
||||||
- Leave dropdown menu open after clicking an action
|
|
||||||
- Move current try/catch error handling from view files to module, add it where necessary
|
|
||||||
- Display checkboxes in status card and fetch statuses only when status card was rendered from Statuses by instance page
|
|
||||||
- Move statuses by instance state from local state to store state
|
|
||||||
- Pass user's ID to actions that moderate users when action is called from user's profile page
|
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Optimistic update for actions in users module and fetching users after api function finished its execution
|
- Optimistic update for actions in users module and fetching users after api function finished its execution
|
||||||
- Relay management
|
- Relay management
|
||||||
- Ability to fetch all statuses from a given instance
|
- 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
|
- Ability to confirm users' emails and resend confirmation emails
|
||||||
- Report notes
|
- Report notes
|
||||||
- Ability to moderate users on the statuses page
|
- Ability to moderate users on the statuses page
|
||||||
- Ability to moderate user on the user's page
|
- Ability to moderate user on the user's page
|
||||||
|
- Ability to remove setting's updated value and set it back to initial value
|
||||||
- Ability to restart an application when settings that require instance reboot were changed
|
- Ability to restart an application when settings that require instance reboot were changed
|
||||||
- Mobile UI for Settings tab
|
- Mobile and Tablet UI for all sections
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- **breaking** PleromaFE login feature relies on `admin` scope presence in PleromaFE token (older versions of PleromaFE don't support it)
|
||||||
|
- `mailerEnabled` must be set to `true` in order to require password reset (password reset currently only works via email)
|
||||||
|
- Render inputs for configuring settings based on description that comes from the BE
|
||||||
|
- Remove fetching initial data for configuring server settings
|
||||||
|
- Actions in users module (ActivateUsers, AddRight, DeactivateUsers, DeleteRight, DeleteUsers) now accept an array of users instead of one user
|
||||||
|
- Leave dropdown menu open after clicking an action
|
||||||
|
- Display checkboxes in status card and fetch statuses only when status card was rendered from Statuses by instance page
|
||||||
|
- Move statuses by instance state from local state to store state
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
@ -39,6 +37,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Remove duplicated success message
|
- Remove duplicated success message
|
||||||
- Fix styles for Statuses by instance page
|
- Fix styles for Statuses by instance page
|
||||||
- Fix styles for Reports section
|
- Fix styles for Reports section
|
||||||
|
- Fix listing remote emoji
|
||||||
|
|
||||||
## [1.2.0] - 2019-09-27
|
## [1.2.0] - 2019-09-27
|
||||||
|
|
||||||
|
|
|
@ -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: [] }
|
{ 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) {
|
export async function fetchReports(filter, page, pageSize, authHost, token) {
|
||||||
return filter.length > 0
|
return filter.length > 0
|
||||||
? Promise.resolve({ data: { reports: reports.filter(report => report.state === filter) }})
|
? Promise.resolve({ data: { reports: reports.filter(report => report.state === filter) }})
|
||||||
: Promise.resolve({ data: { reports }})
|
: Promise.resolve({ data: { reports }})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchGroupedReports(authHost, token) {
|
|
||||||
return Promise.resolve({ data: { reports: groupedReports }})
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function changeState(reportsData, authHost, token) {
|
export async function changeState(reportsData, authHost, token) {
|
||||||
return Promise.resolve({ data: '' })
|
return Promise.resolve({ data: '' })
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
export async function createNote(content, reportID, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
|
|
|
@ -273,7 +273,6 @@ export default {
|
||||||
},
|
},
|
||||||
reports: {
|
reports: {
|
||||||
reports: 'Reports',
|
reports: 'Reports',
|
||||||
groupedReports: 'Grouped reports',
|
|
||||||
reply: 'Reply',
|
reply: 'Reply',
|
||||||
from: 'From',
|
from: 'From',
|
||||||
showNotes: 'Show notes',
|
showNotes: 'Show notes',
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
import { changeState, fetchReports, fetchGroupedReports, createNote, deleteNote } from '@/api/reports'
|
import { changeState, fetchReports, createNote, deleteNote } from '@/api/reports'
|
||||||
|
|
||||||
const reports = {
|
const reports = {
|
||||||
state: {
|
state: {
|
||||||
fetchedReports: [],
|
fetchedReports: [],
|
||||||
fetchedGroupedReports: [],
|
|
||||||
totalReportsCount: 0,
|
totalReportsCount: 0,
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
pageSize: 50,
|
pageSize: 50,
|
||||||
groupReports: false,
|
|
||||||
stateFilter: '',
|
stateFilter: '',
|
||||||
loading: true
|
loading: true
|
||||||
},
|
},
|
||||||
|
@ -24,17 +22,11 @@ const reports = {
|
||||||
SET_REPORTS: (state, reports) => {
|
SET_REPORTS: (state, reports) => {
|
||||||
state.fetchedReports = reports
|
state.fetchedReports = reports
|
||||||
},
|
},
|
||||||
SET_GROUPED_REPORTS: (state, reports) => {
|
|
||||||
state.fetchedGroupedReports = reports
|
|
||||||
},
|
|
||||||
SET_REPORTS_COUNT: (state, total) => {
|
SET_REPORTS_COUNT: (state, total) => {
|
||||||
state.totalReportsCount = total
|
state.totalReportsCount = total
|
||||||
},
|
},
|
||||||
SET_REPORTS_FILTER: (state, filter) => {
|
SET_REPORTS_FILTER: (state, filter) => {
|
||||||
state.stateFilter = filter
|
state.stateFilter = filter
|
||||||
},
|
|
||||||
SET_REPORTS_GROUPING: (state) => {
|
|
||||||
state.groupReports = !state.groupReports
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
@ -46,14 +38,7 @@ const reports = {
|
||||||
return updatedReportsIds.includes(report.id) ? { ...report, state: reportsData[0].state } : report
|
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_REPORTS', updatedReports)
|
||||||
commit('SET_GROUPED_REPORTS', updatedGroupedReports)
|
|
||||||
},
|
},
|
||||||
ClearFetchedReports({ commit }) {
|
ClearFetchedReports({ commit }) {
|
||||||
commit('SET_REPORTS', [])
|
commit('SET_REPORTS', [])
|
||||||
|
@ -67,19 +52,9 @@ const reports = {
|
||||||
commit('SET_PAGE', page)
|
commit('SET_PAGE', page)
|
||||||
commit('SET_LOADING', false)
|
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) {
|
SetFilter({ commit }, filter) {
|
||||||
commit('SET_REPORTS_FILTER', filter)
|
commit('SET_REPORTS_FILTER', filter)
|
||||||
},
|
},
|
||||||
ToggleReportsGrouping({ commit }) {
|
|
||||||
commit('SET_REPORTS_GROUPING')
|
|
||||||
},
|
|
||||||
CreateReportNote({ commit, getters, state, rootState }, { content, reportID }) {
|
CreateReportNote({ commit, getters, state, rootState }, { content, reportID }) {
|
||||||
createNote(content, reportID, getters.authHost, getters.token)
|
createNote(content, reportID, getters.authHost, getters.token)
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,6 @@ const status = {
|
||||||
dispatch('FetchUserStatuses', { userId, godmode })
|
dispatch('FetchUserStatuses', { userId, godmode })
|
||||||
} else if (fetchStatusesByInstance) { // called from Statuses by Instance
|
} else if (fetchStatusesByInstance) { // called from Statuses by Instance
|
||||||
dispatch('FetchStatusesByInstance')
|
dispatch('FetchStatusesByInstance')
|
||||||
} else { // called from GroupedReports
|
|
||||||
dispatch('FetchGroupedReports')
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async DeleteStatus({ dispatch, getters }, { statusId, reportCurrentPage, userId, godmode, fetchStatusesByInstance }) {
|
async DeleteStatus({ dispatch, getters }, { statusId, reportCurrentPage, userId, godmode, fetchStatusesByInstance }) {
|
||||||
|
@ -48,8 +46,6 @@ const status = {
|
||||||
dispatch('FetchUserStatuses', { userId, godmode })
|
dispatch('FetchUserStatuses', { userId, godmode })
|
||||||
} else if (fetchStatusesByInstance) { // called from Statuses by Instance
|
} else if (fetchStatusesByInstance) { // called from Statuses by Instance
|
||||||
dispatch('FetchStatusesByInstance')
|
dispatch('FetchStatusesByInstance')
|
||||||
} else { // called from GroupedReports
|
|
||||||
dispatch('FetchGroupedReports')
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async FetchStatusesByInstance({ commit, getters, state }) {
|
async FetchStatusesByInstance({ commit, getters, state }) {
|
||||||
|
|
|
@ -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>
|
|
|
@ -180,6 +180,9 @@ export default {
|
||||||
height: 15px;
|
height: 15px;
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
.divider {
|
||||||
|
margin: 15px 0;
|
||||||
|
}
|
||||||
.el-card__body {
|
.el-card__body {
|
||||||
padding: 17px;
|
padding: 17px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,14 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="reports-container">
|
<div class="reports-container">
|
||||||
<h1 v-if="groupReports">
|
<h1>
|
||||||
{{ $t('reports.groupedReports') }}
|
|
||||||
<span class="report-count">({{ normalizedReportsCount }})</span>
|
|
||||||
</h1>
|
|
||||||
<h1 v-else>
|
|
||||||
{{ $t('reports.reports') }}
|
{{ $t('reports.reports') }}
|
||||||
<span class="report-count">({{ normalizedReportsCount }})</span>
|
<span class="report-count">({{ normalizedReportsCount }})</span>
|
||||||
</h1>
|
</h1>
|
||||||
<div class="reports-filter-container">
|
<div class="reports-filter-container">
|
||||||
<reports-filter v-if="!groupReports"/>
|
<reports-filter/>
|
||||||
<el-checkbox v-model="groupReports" class="group-reports-checkbox">
|
|
||||||
Group reports by statuses
|
|
||||||
</el-checkbox>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<grouped-report v-loading="loading" v-if="groupReports" :grouped-reports="groupedReports"/>
|
<report v-loading="loading" :reports="reports"/>
|
||||||
<report v-loading="loading" v-else :reports="reports"/>
|
|
||||||
<div v-if="reports.length === 0" class="no-reports-message">
|
<div v-if="reports.length === 0" class="no-reports-message">
|
||||||
<p>There are no reports to display</p>
|
<p>There are no reports to display</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -25,32 +17,18 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import GroupedReport from './components/GroupedReport'
|
|
||||||
import numeral from 'numeral'
|
import numeral from 'numeral'
|
||||||
import Report from './components/Report'
|
import Report from './components/Report'
|
||||||
import ReportsFilter from './components/ReportsFilter'
|
import ReportsFilter from './components/ReportsFilter'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { GroupedReport, Report, ReportsFilter },
|
components: { Report, ReportsFilter },
|
||||||
computed: {
|
computed: {
|
||||||
groupedReports() {
|
|
||||||
return this.$store.state.reports.fetchedGroupedReports
|
|
||||||
},
|
|
||||||
groupReports: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.reports.groupReports
|
|
||||||
},
|
|
||||||
set() {
|
|
||||||
this.toggleReportsGrouping()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
loading() {
|
loading() {
|
||||||
return this.$store.state.reports.loading
|
return this.$store.state.reports.loading
|
||||||
},
|
},
|
||||||
normalizedReportsCount() {
|
normalizedReportsCount() {
|
||||||
return this.groupReports
|
return numeral(this.$store.state.reports.totalReportsCount).format('0a')
|
||||||
? numeral(this.$store.state.reports.fetchedGroupedReports.length).format('0a')
|
|
||||||
: numeral(this.$store.state.reports.totalReportsCount).format('0a')
|
|
||||||
},
|
},
|
||||||
reports() {
|
reports() {
|
||||||
return this.$store.state.reports.fetchedReports
|
return this.$store.state.reports.fetchedReports
|
||||||
|
@ -58,12 +36,6 @@ export default {
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$store.dispatch('FetchReports', 1)
|
this.$store.dispatch('FetchReports', 1)
|
||||||
this.$store.dispatch('FetchGroupedReports')
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
toggleReportsGrouping() {
|
|
||||||
this.$store.dispatch('ToggleReportsGrouping')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -77,9 +49,6 @@ export default {
|
||||||
margin: 22px 15px 22px 15px;
|
margin: 22px 15px 22px 15px;
|
||||||
padding-bottom: 0
|
padding-bottom: 0
|
||||||
}
|
}
|
||||||
.group-reports-checkbox {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
h1 {
|
h1 {
|
||||||
margin: 22px 0 0 15px;
|
margin: 22px 0 0 15px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
|
||||||
})
|
|
||||||
})
|
|
Loading…
Reference in a new issue