Extract dropdown for moderating users into separate component and rename timeline item to report

This commit is contained in:
Angelina Filippova 2019-09-25 19:08:43 +03:00
parent 47e60b11a7
commit c9e9b62955
4 changed files with 153 additions and 93 deletions

View file

@ -0,0 +1,86 @@
<template>
<el-dropdown trigger="click">
<el-button plain size="small" icon="el-icon-files">{{ $t('reports.moderateUser') }}
<i class="el-icon-arrow-down el-icon--right"/>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-if="showDeactivatedButton(report.account)"
@click.native="handleDeactivation(report.account)">
{{ report.account.deactivated ? $t('users.activateAccount') : $t('users.deactivateAccount') }}
</el-dropdown-item>
<el-dropdown-item
v-if="showDeactivatedButton(report.account.id)"
@click.native="handleDeletion(report.account.id)">
{{ $t('users.deleteAccount') }}
</el-dropdown-item>
<el-dropdown-item
:divided="true"
:class="{ 'active-tag': report.account.tags.includes('force_nsfw') }"
@click.native="toggleTag(report.account, 'force_nsfw')">
{{ $t('users.forceNsfw') }}
<i v-if="report.account.tags.includes('force_nsfw')" class="el-icon-check"/>
</el-dropdown-item>
<el-dropdown-item
:class="{ 'active-tag': report.account.tags.includes('strip_media') }"
@click.native="toggleTag(report.account, 'strip_media')">
{{ $t('users.stripMedia') }}
<i v-if="report.account.tags.includes('strip_media')" class="el-icon-check"/>
</el-dropdown-item>
<el-dropdown-item
:class="{ 'active-tag': report.account.tags.includes('force_unlisted') }"
@click.native="toggleTag(report.account, 'force_unlisted')">
{{ $t('users.forceUnlisted') }}
<i v-if="report.account.tags.includes('force_unlisted')" class="el-icon-check"/>
</el-dropdown-item>
<el-dropdown-item
:class="{ 'active-tag': report.account.tags.includes('sandbox') }"
@click.native="toggleTag(report.account, 'sandbox')">
{{ $t('users.sandbox') }}
<i v-if="report.account.tags.includes('sandbox')" class="el-icon-check"/>
</el-dropdown-item>
<el-dropdown-item
v-if="report.account.local"
:class="{ 'active-tag': report.account.tags.includes('disable_remote_subscription') }"
@click.native="toggleTag(report.account, 'disable_remote_subscription')">
{{ $t('users.disableRemoteSubscription') }}
<i v-if="report.account.tags.includes('disable_remote_subscription')" class="el-icon-check"/>
</el-dropdown-item>
<el-dropdown-item
v-if="report.account.local"
:class="{ 'active-tag': report.account.tags.includes('disable_any_subscription') }"
@click.native="toggleTag(report.account, 'disable_any_subscription')">
{{ $t('users.disableAnySubscription') }}
<i v-if="report.account.tags.includes('disable_any_subscription')" class="el-icon-check"/>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
export default {
name: 'ModerateUserDropdown',
props: {
report: {
type: Object,
required: true
}
},
methods: {
handleDeactivation({ nickname }) {
this.$store.dispatch('ToggleUserActivation', nickname)
},
handleDeletion(user) {
this.$store.dispatch('DeleteUser', user)
},
showDeactivatedButton(id) {
return this.$store.state.user.id !== id
},
toggleTag(user, tag) {
user.tags.includes(tag)
? this.$store.dispatch('RemoveTag', { users: [user], tag })
: this.$store.dispatch('AddTag', { users: [user], tag })
}
}
}
</script>

View file

@ -16,60 +16,7 @@
<el-dropdown-item v-if="report.state !== 'closed'" @click.native="changeReportState('closed', report.id)">{{ $t('reports.close') }}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-dropdown trigger="click">
<el-button plain size="small" icon="el-icon-files">{{ $t('reports.moderateUser') }}<i class="el-icon-arrow-down el-icon--right"/></el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-if="showDeactivatedButton(report.account)"
@click.native="handleDeactivation(report.account)">
{{ report.account.deactivated ? $t('users.activateAccount') : $t('users.deactivateAccount') }}
</el-dropdown-item>
<el-dropdown-item
v-if="showDeactivatedButton(report.account.id)"
@click.native="handleDeletion(report.account.id)">
{{ $t('users.deleteAccount') }}
</el-dropdown-item>
<el-dropdown-item
:divided="true"
:class="{ 'active-tag': report.account.tags.includes('force_nsfw') }"
@click.native="toggleTag(report.account, 'force_nsfw')">
{{ $t('users.forceNsfw') }}
<i v-if="report.account.tags.includes('force_nsfw')" class="el-icon-check"/>
</el-dropdown-item>
<el-dropdown-item
:class="{ 'active-tag': report.account.tags.includes('strip_media') }"
@click.native="toggleTag(report.account, 'strip_media')">
{{ $t('users.stripMedia') }}
<i v-if="report.account.tags.includes('strip_media')" class="el-icon-check"/>
</el-dropdown-item>
<el-dropdown-item
:class="{ 'active-tag': report.account.tags.includes('force_unlisted') }"
@click.native="toggleTag(report.account, 'force_unlisted')">
{{ $t('users.forceUnlisted') }}
<i v-if="report.account.tags.includes('force_unlisted')" class="el-icon-check"/>
</el-dropdown-item>
<el-dropdown-item
:class="{ 'active-tag': report.account.tags.includes('sandbox') }"
@click.native="toggleTag(report.account, 'sandbox')">
{{ $t('users.sandbox') }}
<i v-if="report.account.tags.includes('sandbox')" class="el-icon-check"/>
</el-dropdown-item>
<el-dropdown-item
v-if="report.account.local"
:class="{ 'active-tag': report.account.tags.includes('disable_remote_subscription') }"
@click.native="toggleTag(report.account, 'disable_remote_subscription')">
{{ $t('users.disableRemoteSubscription') }}
<i v-if="report.account.tags.includes('disable_remote_subscription')" class="el-icon-check"/>
</el-dropdown-item>
<el-dropdown-item
v-if="report.account.local"
:class="{ 'active-tag': report.account.tags.includes('disable_any_subscription') }"
@click.native="toggleTag(report.account, 'disable_any_subscription')">
{{ $t('users.disableAnySubscription') }}
<i v-if="report.account.tags.includes('disable_any_subscription')" class="el-icon-check"/>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<moderate-user-dropdown :report="report"/>
</div>
</div>
<div>
@ -112,10 +59,11 @@
<script>
import moment from 'moment'
import Statuses from './Statuses'
import ModerateUserDropdown from './ModerateUserDropdown'
export default {
name: 'TimelineItem',
components: { Statuses },
name: 'Report',
components: { Statuses, ModerateUserDropdown },
props: {
report: {
type: Object,
@ -141,20 +89,6 @@ export default {
},
parseTimestamp(timestamp) {
return moment(timestamp).format('L HH:mm')
},
showDeactivatedButton(id) {
return this.$store.state.user.id !== id
},
handleDeactivation({ nickname }) {
this.$store.dispatch('ToggleUserActivation', nickname)
},
handleDeletion(user) {
this.$store.dispatch('DeleteUser', user)
},
toggleTag(user, tag) {
user.tags.includes(tag)
? this.$store.dispatch('RemoveTag', { users: [user], tag })
: this.$store.dispatch('AddTag', { users: [user], tag })
}
}
}

View file

@ -3,30 +3,55 @@
<h1>{{ $t('reports.reports') }}</h1>
<div class="filter-container">
<reports-filter/>
<el-checkbox v-model="groupReports" class="group-reports-checkbox" @change="toggleReportsGrouping">
Group reports by statuses
</el-checkbox>
</div>
<div class="block">
<el-timeline class="timeline">
<timeline-item v-loading="loading" v-for="report in reports" :report="report" :key="report.id"/>
<report v-loading="loading" v-for="report in reports" :report="report" :key="report.id"/>
</el-timeline>
<div v-if="reports.length === 0" class="no-reports-message">
<p>There are no reports to display</p>
</div>
<div v-if="!loading" class="reports-pagination">
<el-pagination
:total="totalReportsCount"
:current-page="currentPage"
:page-size="pageSize"
background
layout="prev, pager, next"
@current-change="handlePageChange"
/>
</div>
</div>
</div>
</template>
<script>
import TimelineItem from './components/TimelineItem'
import Report from './components/Report'
import ReportsFilter from './components/ReportsFilter'
export default {
components: { TimelineItem, ReportsFilter },
components: { Report, ReportsFilter },
computed: {
groupReports() {
return this.$store.state.reports.groupReports
},
loading() {
return this.$store.state.users.loading
return this.$store.state.reports.loading
},
pageSize() {
return this.$store.state.reports.pageSize
},
reports() {
return this.$store.state.reports.fetchedReports
},
totalReportsCount() {
return this.$store.state.reports.totalReportsCount
},
currentPage() {
return this.$store.state.reports.currentPage
}
},
mounted() {
@ -35,16 +60,22 @@ export default {
created() {
window.addEventListener('scroll', this.handleScroll)
},
destroyed() {
window.removeEventListener('scroll', this.handleScroll)
},
// destroyed() {
// window.removeEventListener('scroll', this.handleScroll)
// },
methods: {
handleScroll(reports) {
const bottomOfWindow = document.documentElement.scrollHeight - document.documentElement.scrollTop === document.documentElement.clientHeight
if (bottomOfWindow) {
this.$store.dispatch('FetchReports')
}
handlePageChange(page) {
this.$store.dispatch('FetchReports', { page })
},
toggleReportsGrouping() {
}
// handleScroll(reports) {
// const bottomOfWindow = document.documentElement.scrollHeight - document.documentElement.scrollTop === document.documentElement.clientHeight
// if (bottomOfWindow) {
// this.$store.dispatch('FetchReports')
// }
// }
}
}
</script>
@ -56,9 +87,14 @@ export default {
padding: 0px;
}
.filter-container {
display: flex;
flex-direction: column;
margin: 22px 15px 22px 15px;
padding-bottom: 0
}
.group-reports-checkbox {
margin-top: 10px;
}
h1 {
margin: 22px 0 0 15px;
}
@ -78,9 +114,13 @@ only screen and (max-width: 760px),
.filter-container {
margin: 0 10px
}
.timeline {
margin: 20px 20px 20px 18px
}
}
#app > div > div.main-container > section > div > div.block > ul {
margin: 45px 45px 5px 19px;
}
.reports-pagination {
margin: 25px 0;
text-align: center;
}
}
</style>

View file

@ -1,7 +1,7 @@
import Vuex from 'vuex'
import { mount, createLocalVue, config } from '@vue/test-utils'
import Element from 'element-ui'
import TimelineItem from '@/views/reports/components/TimelineItem'
import Report from '@/views/reports/components/Report'
import storeConfig from './store.conf'
import { cloneDeep } from 'lodash'
import flushPromises from 'flush-promises'
@ -25,7 +25,7 @@ describe('Report in a timeline', () => {
it('changes report state from open to resolved', async (done) => {
const report = store.state.reports.fetchedReports[0]
const wrapper = mount(TimelineItem, {
const wrapper = mount(Report, {
store,
localVue,
propsData: {
@ -43,7 +43,7 @@ describe('Report in a timeline', () => {
it('changes report state from open to closed', async (done) => {
const report = store.state.reports.fetchedReports[3]
const wrapper = mount(TimelineItem, {
const wrapper = mount(Report, {
store,
localVue,
propsData: {
@ -61,7 +61,7 @@ describe('Report in a timeline', () => {
it('shows statuses', () => {
const report = store.state.reports.fetchedReports[4]
const wrapper = mount(TimelineItem, {
const wrapper = mount(Report, {
store,
localVue,
propsData: {
@ -75,7 +75,7 @@ describe('Report in a timeline', () => {
it('adds sensitive flag to a status', async (done) => {
const report = store.state.reports.fetchedReports[4]
const wrapper = mount(TimelineItem, {
const wrapper = mount(Report, {
store,
localVue,
propsData: {
@ -93,7 +93,7 @@ describe('Report in a timeline', () => {
it('removes sensitive flag to a status', async (done) => {
const report = store.state.reports.fetchedReports[4]
const wrapper = mount(TimelineItem, {
const wrapper = mount(Report, {
store,
localVue,
propsData: {
@ -111,7 +111,7 @@ describe('Report in a timeline', () => {
it('changes status visibility from public to unlisted', async (done) => {
const report = store.state.reports.fetchedReports[4]
const wrapper = mount(TimelineItem, {
const wrapper = mount(Report, {
store,
localVue,
propsData: {
@ -129,7 +129,7 @@ describe('Report in a timeline', () => {
it('changes status visibility from unlisted to private', async (done) => {
const report = store.state.reports.fetchedReports[4]
const wrapper = mount(TimelineItem, {
const wrapper = mount(Report, {
store,
localVue,
propsData: {