Extract Report content into a separate component and reuse it in single report component

This commit is contained in:
Angelina Filippova 2020-10-27 01:46:51 +03:00
parent 3f31748e08
commit 855f8640b2
3 changed files with 190 additions and 148 deletions

View file

@ -28,83 +28,7 @@
</div> </div>
</div> </div>
<el-divider class="divider"/> <el-divider class="divider"/>
<div class="report-account-container"> <report-content :report="report"/>
<span class="report-row-key">{{ $t('reports.account') }}:</span>
<div class="report-account">
<router-link
v-if="propertyExists(report.account, 'id')"
:to="{ name: 'UsersShow', params: { id: report.account.id }}"
class="router-link">
<img
v-if="propertyExists(report.account, 'avatar')"
:src="report.account.avatar"
alt="avatar"
class="avatar-img">
<span v-if="propertyExists(report.account, 'nickname')" class="report-account-name">{{ report.account.nickname }}</span>
<span v-else class="report-account-name deactivated">({{ $t('users.invalidNickname') }})</span>
</router-link>
<span v-else class="report-account-name deactivated">({{ $t('users.invalidNickname') }})</span>
<a v-if="propertyExists(report.account, 'url')" :href="report.account.url" target="_blank" class="account">
{{ $t('userProfile.openAccountInInstance') }}
<i class="el-icon-top-right"/>
</a>
</div>
</div>
<div v-if="report.content && report.content.length > 0">
<el-divider class="divider"/>
<span class="report-row-key">{{ $t('reports.content') }}:
<span>{{ report.content }}</span>
</span>
</div>
<el-divider class="divider"/>
<div :style="showStatuses(report.statuses) ? '' : 'margin-bottom:15px'" class="report-account-container">
<span class="report-row-key">{{ $t('reports.actor') }}:</span>
<div class="report-account">
<router-link
v-if="propertyExists(report.actor, 'id')"
:to="{ name: 'UsersShow', params: { id: report.actor.id }}"
class="router-link">
<img
v-if="propertyExists(report.actor, 'avatar')"
:src="report.actor.avatar"
alt="avatar"
class="avatar-img">
<span v-if="propertyExists(report.actor, 'nickname')" class="report-account-name">{{ report.actor.nickname }}</span>
<span v-else class="report-account-name deactivated">({{ $t('users.invalidNickname') }})</span>
</router-link>
<span v-else class="report-account-name deactivated">({{ $t('users.invalidNickname') }})</span>
<a v-if="propertyExists(report.actor, 'url')" :href="report.actor.url" target="_blank" class="account">
{{ $t('userProfile.openAccountInInstance') }}
<i class="el-icon-top-right"/>
</a>
</div>
</div>
<div v-if="showStatuses(report.statuses)" class="reported-statuses">
<el-collapse>
<el-collapse-item :title="getStatusesTitle(report.statuses)">
<div v-for="status in report.statuses" :key="status.id">
<status :status="status" :account="status.account.nickname ? status.account : report.account" :show-checkbox="false" :page="currentPage"/>
</div>
</el-collapse-item>
</el-collapse>
</div>
<div class="report-notes">
<el-collapse>
<el-collapse-item :title="getNotesTitle(report.notes)">
<note-card v-for="(note, index) in report.notes" :key="index" :note="note" :report="report"/>
</el-collapse-item>
</el-collapse>
<div class="report-note-form">
<el-input
v-model="notes[report.id]"
:placeholder="$t('reports.leaveNote')"
type="textarea"
rows="2"/>
<div class="report-post-note">
<el-button @click="handleNewNote(report.id)">{{ $t('reports.postNote') }}</el-button>
</div>
</div>
</div>
</el-card> </el-card>
</el-timeline-item> </el-timeline-item>
</el-timeline> </el-timeline>
@ -123,24 +47,18 @@
<script> <script>
import moment from 'moment' import moment from 'moment'
import NoteCard from './NoteCard'
import Status from '@/components/Status'
import ModerateUserDropdown from './ModerateUserDropdown' import ModerateUserDropdown from './ModerateUserDropdown'
import ReportContent from './ReportContent'
export default { export default {
name: 'Report', name: 'Report',
components: { Status, ModerateUserDropdown, NoteCard }, components: { ModerateUserDropdown, ReportContent },
props: { props: {
reports: { reports: {
type: Array, type: Array,
required: true required: true
} }
}, },
data() {
return {
notes: {}
}
},
computed: { computed: {
loading() { loading() {
return this.$store.state.reports.loading return this.$store.state.reports.loading
@ -172,16 +90,6 @@ export default {
return 'primary' return 'primary'
} }
}, },
getStatusesTitle(statuses = []) {
return `Reported statuses: ${statuses.length} item(s)`
},
getNotesTitle(notes = []) {
return `Notes: ${notes.length} item(s)`
},
handleNewNote(reportID) {
this.$store.dispatch('CreateReportNote', { content: this.notes[reportID], reportID })
this.notes[reportID] = ''
},
handlePageChange(page) { handlePageChange(page) {
this.$store.dispatch('FetchReports', page) this.$store.dispatch('FetchReports', page)
}, },
@ -193,9 +101,6 @@ export default {
return account[property] && account[_secondProperty] return account[property] && account[_secondProperty]
} }
return account[property] return account[property]
},
showStatuses(statuses = []) {
return statuses.length > 0
} }
} }
} }
@ -206,25 +111,9 @@ export default {
margin: 0; margin: 0;
height: 17px; height: 17px;
} }
.account {
line-height: 26px;
font-size: 13px;
color: #606266;
}
.account:hover {
text-decoration: underline;
}
.avatar-img {
vertical-align: bottom;
width: 15px;
height: 15px;
}
.divider { .divider {
margin: 15px 0; margin: 15px 0;
} }
.deactivated {
color: gray;
}
.el-card__body { .el-card__body {
padding: 17px; padding: 17px;
} }
@ -279,35 +168,9 @@ export default {
height: 40px; height: 40px;
} }
} }
.report-account {
display: flex;
align-items: baseline;
justify-content: space-between;
flex-grow: 2;
}
.report-account-container {
display: flex;
align-items: baseline;
}
.report-account-name {
font-size: 15px;
font-weight: 500;
}
.report-row-key {
font-size: 14px;
font-weight: 500;
padding-right: 5px;
}
.report-title { .report-title {
margin: 0; margin: 0;
} }
.report-note-form {
margin: 15px 0 0 0;
}
.report-post-note {
margin: 5px 0 0 0;
text-align: right;
}
.reports-pagination { .reports-pagination {
margin: 25px 0; margin: 25px 0;
text-align: center; text-align: center;
@ -316,12 +179,6 @@ export default {
margin: 30px 45px 45px 19px; margin: 30px 45px 45px 19px;
padding: 0px; padding: 0px;
} }
.router-link {
text-decoration: none;
}
.reported-statuses {
margin-top: 15px;
}
.submit-button { .submit-button {
display: block; display: block;
margin: 7px 0 17px auto; margin: 7px 0 17px auto;

View file

@ -0,0 +1,182 @@
<template>
<div>
<div class="report-account-container">
<span class="report-row-key">{{ $t('reports.account') }}:</span>
<div class="report-account">
<router-link
v-if="propertyExists(report.account, 'id')"
:to="{ name: 'UsersShow', params: { id: report.account.id }}"
class="router-link">
<img
v-if="propertyExists(report.account, 'avatar')"
:src="report.account.avatar"
alt="avatar"
class="avatar-img">
<span v-if="propertyExists(report.account, 'nickname')" class="report-account-name">{{ report.account.nickname }}</span>
<span v-else class="report-account-name deactivated">({{ $t('users.invalidNickname') }})</span>
</router-link>
<span v-else class="report-account-name deactivated">({{ $t('users.invalidNickname') }})</span>
<a v-if="propertyExists(report.account, 'url')" :href="report.account.url" target="_blank" class="account">
{{ $t('userProfile.openAccountInInstance') }}
<i class="el-icon-top-right"/>
</a>
</div>
</div>
<div v-if="report.content && report.content.length > 0">
<el-divider class="divider"/>
<span class="report-row-key">{{ $t('reports.content') }}:
<span>{{ report.content }}</span>
</span>
</div>
<el-divider class="divider"/>
<div :style="showStatuses(report.statuses) ? '' : 'margin-bottom:15px'" class="report-account-container">
<span class="report-row-key">{{ $t('reports.actor') }}:</span>
<div class="report-account">
<router-link
v-if="propertyExists(report.actor, 'id')"
:to="{ name: 'UsersShow', params: { id: report.actor.id }}"
class="router-link">
<img
v-if="propertyExists(report.actor, 'avatar')"
:src="report.actor.avatar"
alt="avatar"
class="avatar-img">
<span v-if="propertyExists(report.actor, 'nickname')" class="report-account-name">{{ report.actor.nickname }}</span>
<span v-else class="report-account-name deactivated">({{ $t('users.invalidNickname') }})</span>
</router-link>
<span v-else class="report-account-name deactivated">({{ $t('users.invalidNickname') }})</span>
<a v-if="propertyExists(report.actor, 'url')" :href="report.actor.url" target="_blank" class="account">
{{ $t('userProfile.openAccountInInstance') }}
<i class="el-icon-top-right"/>
</a>
</div>
</div>
<div v-if="showStatuses(report.statuses)" class="reported-statuses">
<el-collapse>
<el-collapse-item :title="getStatusesTitle(report.statuses)">
<div v-for="status in report.statuses" :key="status.id">
<status :status="status" :account="status.account.nickname ? status.account : report.account" :show-checkbox="false" :page="currentPage"/> // check why it's currentPage here
</div>
</el-collapse-item>
</el-collapse>
</div>
<div>
<el-collapse>
<el-collapse-item :title="getNotesTitle(report.notes)">
<note-card v-for="(note, index) in report.notes" :key="index" :note="note" :report="report"/>
</el-collapse-item>
</el-collapse>
<div class="report-note-form">
<el-input
v-model="notes[report.id]"
:placeholder="$t('reports.leaveNote')"
type="textarea"
rows="2"/>
<div class="report-post-note">
<el-button @click="handleNewNote(report.id)">{{ $t('reports.postNote') }}</el-button>
</div>
</div>
</div>
</div>
</template>
<script>
import NoteCard from './NoteCard'
import Status from '@/components/Status'
export default {
name: 'ReportContent',
components: { NoteCard, Status },
props: {
report: {
type: Object,
required: true
}
},
data() {
return {
notes: {}
}
},
computed: {
currentPage() {
return this.$store.state.reports.currentPage
}
},
methods: {
getNotesTitle(notes = []) {
return `Notes: ${notes.length} item(s)`
},
getStatusesTitle(statuses = []) {
return `Reported statuses: ${statuses.length} item(s)`
},
handleNewNote(reportID) {
this.$store.dispatch('CreateReportNote', { content: this.notes[reportID], reportID })
this.notes[reportID] = ''
},
propertyExists(account, property, _secondProperty) {
if (_secondProperty) {
return account[property] && account[_secondProperty]
}
return account[property]
},
showStatuses(statuses = []) {
return statuses.length > 0
}
}
}
</script>
<style rel='stylesheet/scss' lang='scss'>
.account {
line-height: 26px;
font-size: 13px;
color: #606266;
}
.account:hover {
text-decoration: underline;
}
.avatar-img {
vertical-align: bottom;
width: 15px;
height: 15px;
}
.deactivated {
color: gray;
}
.divider {
margin: 15px 0;
}
.report-account {
display: flex;
align-items: baseline;
justify-content: space-between;
flex-grow: 2;
}
.report-account-container {
display: flex;
align-items: baseline;
}
.report-account-name {
font-size: 15px;
font-weight: 500;
}
.report-note-form {
margin: 15px 0 0 0;
}
.report-post-note {
margin: 5px 0 0 0;
text-align: right;
}
.report-row-key {
font-size: 14px;
font-weight: 500;
padding-right: 5px;
}
.reported-statuses {
margin-top: 15px;
}
.router-link {
text-decoration: none;
}
</style>

View file

@ -15,16 +15,19 @@
</div> </div>
<reboot-button/> <reboot-button/>
</header> </header>
<el-card class="report"/> <el-card class="report">
<report-content :report="report"/>
</el-card>
</div> </div>
</template> </template>
<script> <script>
import RebootButton from '@/components/RebootButton' import RebootButton from '@/components/RebootButton'
import ReportContent from './components/ReportContent'
export default { export default {
name: 'ReportsShow', name: 'ReportsShow',
components: { RebootButton }, components: { RebootButton, ReportContent },
computed: { computed: {
loading() { loading() {
return this.$store.state.reports.loading return this.$store.state.reports.loading