Skip to content
Snippets Groups Projects
Commit c9e9b629 authored by Angelina Filippova's avatar Angelina Filippova
Browse files

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

parent 47e60b11
No related branches found
No related tags found
No related merge requests found
<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>
......@@ -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 })
}
}
}
......
......@@ -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>
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: {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment