forked from AkkomaGang/admin-fe
Merge branch 'feature/show-open-reports-count' into 'develop'
Show open reports count in Sidebar Menu Closes #128 See merge request pleroma/admin-fe!143
This commit is contained in:
commit
702d989c08
7 changed files with 70 additions and 31 deletions
|
@ -17,6 +17,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Add MRF Activity Expiration setting
|
- Add MRF Activity Expiration setting
|
||||||
- Add ability to disable multi-factor authentication for a user
|
- Add ability to disable multi-factor authentication for a user
|
||||||
- Ability to configure S3 settings on Upload tab
|
- Ability to configure S3 settings on Upload tab
|
||||||
|
- Show number of open reports in Sidebar Menu
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,13 @@ import { changeState, fetchReports, createNote, deleteNote } from '@/api/reports
|
||||||
|
|
||||||
const reports = {
|
const reports = {
|
||||||
state: {
|
state: {
|
||||||
fetchedReports: [],
|
|
||||||
totalReportsCount: 0,
|
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
|
fetchedReports: [],
|
||||||
|
loading: true,
|
||||||
|
openReportsCount: 0,
|
||||||
pageSize: 50,
|
pageSize: 50,
|
||||||
stateFilter: '',
|
stateFilter: '',
|
||||||
loading: true
|
totalReportsCount: 0
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
SET_LAST_REPORT_ID: (state, id) => {
|
SET_LAST_REPORT_ID: (state, id) => {
|
||||||
|
@ -16,6 +17,9 @@ const reports = {
|
||||||
SET_LOADING: (state, status) => {
|
SET_LOADING: (state, status) => {
|
||||||
state.loading = status
|
state.loading = status
|
||||||
},
|
},
|
||||||
|
SET_OPEN_REPORTS_COUNT: (state, total) => {
|
||||||
|
state.openReportsCount = total
|
||||||
|
},
|
||||||
SET_PAGE: (state, page) => {
|
SET_PAGE: (state, page) => {
|
||||||
state.currentPage = page
|
state.currentPage = page
|
||||||
},
|
},
|
||||||
|
@ -30,7 +34,7 @@ const reports = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async ChangeReportState({ commit, getters, state }, reportsData) {
|
async ChangeReportState({ commit, dispatch, getters, state }, reportsData) {
|
||||||
changeState(reportsData, getters.authHost, getters.token)
|
changeState(reportsData, getters.authHost, getters.token)
|
||||||
|
|
||||||
const updatedReports = state.fetchedReports.map(report => {
|
const updatedReports = state.fetchedReports.map(report => {
|
||||||
|
@ -39,6 +43,7 @@ const reports = {
|
||||||
})
|
})
|
||||||
|
|
||||||
commit('SET_REPORTS', updatedReports)
|
commit('SET_REPORTS', updatedReports)
|
||||||
|
dispatch('FetchOpenReportsCount')
|
||||||
},
|
},
|
||||||
ClearFetchedReports({ commit }) {
|
ClearFetchedReports({ commit }) {
|
||||||
commit('SET_REPORTS', [])
|
commit('SET_REPORTS', [])
|
||||||
|
@ -52,7 +57,14 @@ const reports = {
|
||||||
commit('SET_PAGE', page)
|
commit('SET_PAGE', page)
|
||||||
commit('SET_LOADING', false)
|
commit('SET_LOADING', false)
|
||||||
},
|
},
|
||||||
SetFilter({ commit }, filter) {
|
async FetchOpenReportsCount({ commit, getters, state }) {
|
||||||
|
commit('SET_LOADING', true)
|
||||||
|
const { data } = await fetchReports('open', state.currentPage, state.pageSize, getters.authHost, getters.token)
|
||||||
|
|
||||||
|
commit('SET_OPEN_REPORTS_COUNT', data.total)
|
||||||
|
commit('SET_LOADING', false)
|
||||||
|
},
|
||||||
|
SetReportsFilter({ commit }, filter) {
|
||||||
commit('SET_REPORTS_FILTER', filter)
|
commit('SET_REPORTS_FILTER', filter)
|
||||||
},
|
},
|
||||||
CreateReportNote({ commit, getters, state, rootState }, { content, reportID }) {
|
CreateReportNote({ commit, getters, state, rootState }, { content, reportID }) {
|
||||||
|
|
|
@ -1,8 +1,19 @@
|
||||||
|
<template>
|
||||||
|
<span>
|
||||||
|
<svg-icon :icon-class="icon"/>
|
||||||
|
<span slot="title">{{ title }}</span>
|
||||||
|
<el-badge :value="count" type="primary" class="count-badge" />
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'MenuItem',
|
name: 'Item',
|
||||||
functional: true,
|
|
||||||
props: {
|
props: {
|
||||||
|
count: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
icon: {
|
icon: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
|
@ -11,19 +22,13 @@ export default {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
}
|
}
|
||||||
},
|
|
||||||
render(h, context) {
|
|
||||||
const { icon, title } = context.props
|
|
||||||
const vnodes = []
|
|
||||||
|
|
||||||
if (icon) {
|
|
||||||
vnodes.push(<svg-icon icon-class={icon}/>)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (title) {
|
|
||||||
vnodes.push(<span slot='title'>{(title)}</span>)
|
|
||||||
}
|
|
||||||
return vnodes
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style rel='stylesheet/scss' lang='scss' scoped>
|
||||||
|
.count-badge {
|
||||||
|
margin-left: 5px;
|
||||||
|
height: 48px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -4,14 +4,21 @@
|
||||||
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
|
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
|
||||||
<app-link :to="resolvePath(onlyOneChild.path)">
|
<app-link :to="resolvePath(onlyOneChild.path)">
|
||||||
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
|
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
|
||||||
<item v-if="onlyOneChild.meta" :icon="onlyOneChild.meta.icon||item.meta.icon" :title="generateTitle(onlyOneChild.meta.title)" />
|
<item
|
||||||
|
v-if="onlyOneChild.meta"
|
||||||
|
:count="showCount(item) ? normalizedReportsCount : null"
|
||||||
|
:icon="onlyOneChild.meta.icon||item.meta.icon"
|
||||||
|
:title="generateTitle(onlyOneChild.meta.title)" />
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</app-link>
|
</app-link>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-submenu v-else ref="subMenu" :index="resolvePath(item.path)">
|
<el-submenu v-else ref="subMenu" :index="resolvePath(item.path)">
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
<item v-if="item.meta" :icon="item.meta.icon" :title="generateTitle(item.meta.title)" />
|
<item
|
||||||
|
v-if="item.meta"
|
||||||
|
:count="showCount(item) ? normalizedReportsCount : null"
|
||||||
|
:icon="item.meta.icon"
|
||||||
|
:title="generateTitle(item.meta.title)" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-for="child in item.children">
|
<template v-for="child in item.children">
|
||||||
|
@ -26,7 +33,11 @@
|
||||||
|
|
||||||
<app-link v-else :to="resolvePath(child.path)" :key="child.name">
|
<app-link v-else :to="resolvePath(child.path)" :key="child.name">
|
||||||
<el-menu-item :index="resolvePath(child.path)">
|
<el-menu-item :index="resolvePath(child.path)">
|
||||||
<item v-if="child.meta" :icon="child.meta.icon" :title="generateTitle(child.meta.title)" />
|
<item
|
||||||
|
v-if="child.meta"
|
||||||
|
:count="showCount(item) ? normalizedReportsCount : null"
|
||||||
|
:icon="child.meta.icon"
|
||||||
|
:title="generateTitle(child.meta.title)" />
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</app-link>
|
</app-link>
|
||||||
</template>
|
</template>
|
||||||
|
@ -43,6 +54,7 @@ import { isExternal } from '@/utils'
|
||||||
import Item from './Item'
|
import Item from './Item'
|
||||||
import AppLink from './Link'
|
import AppLink from './Link'
|
||||||
import FixiOSBug from './FixiOSBug'
|
import FixiOSBug from './FixiOSBug'
|
||||||
|
import numeral from 'numeral'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SidebarItem',
|
name: 'SidebarItem',
|
||||||
|
@ -71,6 +83,9 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
invitesEnabled() {
|
invitesEnabled() {
|
||||||
return this.basePath === '/invites' ? this.$store.state.app.invitesEnabled : true
|
return this.basePath === '/invites' ? this.$store.state.app.invitesEnabled : true
|
||||||
|
},
|
||||||
|
normalizedReportsCount() {
|
||||||
|
return numeral(this.$store.state.reports.openReportsCount).format('0a')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -104,6 +119,9 @@ export default {
|
||||||
}
|
}
|
||||||
return path.resolve(this.basePath, routePath)
|
return path.resolve(this.basePath, routePath)
|
||||||
},
|
},
|
||||||
|
showCount(item) {
|
||||||
|
return item.path === '/reports'
|
||||||
|
},
|
||||||
isExternalLink(routePath) {
|
isExternalLink(routePath) {
|
||||||
return isExternal(routePath)
|
return isExternal(routePath)
|
||||||
},
|
},
|
||||||
|
|
|
@ -31,6 +31,9 @@ export default {
|
||||||
isCollapse() {
|
isCollapse() {
|
||||||
return !this.sidebar.opened
|
return !this.sidebar.opened
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$store.dispatch('FetchOpenReportsCount')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -38,11 +38,11 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.$store.dispatch('SetFilter', this.$data.filter)
|
this.$store.dispatch('SetReportsFilter', this.$data.filter)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggleFilters() {
|
toggleFilters() {
|
||||||
this.$store.dispatch('SetFilter', this.$data.filter)
|
this.$store.dispatch('SetReportsFilter', this.$data.filter)
|
||||||
this.$store.dispatch('ClearFetchedReports')
|
this.$store.dispatch('ClearFetchedReports')
|
||||||
this.$store.dispatch('FetchReports', 1)
|
this.$store.dispatch('FetchReports', 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ describe('Reports filter', () => {
|
||||||
it('shows open reports when "Open" filter is applied', async (done) => {
|
it('shows open reports when "Open" filter is applied', async (done) => {
|
||||||
expect(store.state.reports.fetchedReports.length).toEqual(7)
|
expect(store.state.reports.fetchedReports.length).toEqual(7)
|
||||||
|
|
||||||
store.dispatch('SetFilter', 'open')
|
store.dispatch('SetReportsFilter', 'open')
|
||||||
store.dispatch('ClearFetchedReports')
|
store.dispatch('ClearFetchedReports')
|
||||||
store.dispatch('FetchReports', 1)
|
store.dispatch('FetchReports', 1)
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
|
@ -38,7 +38,7 @@ describe('Reports filter', () => {
|
||||||
it('shows resolved reports when "Resolved" filter is applied', async (done) => {
|
it('shows resolved reports when "Resolved" filter is applied', async (done) => {
|
||||||
expect(store.state.reports.fetchedReports.length).toEqual(7)
|
expect(store.state.reports.fetchedReports.length).toEqual(7)
|
||||||
|
|
||||||
store.dispatch('SetFilter', 'resolved')
|
store.dispatch('SetReportsFilter', 'resolved')
|
||||||
store.dispatch('ClearFetchedReports')
|
store.dispatch('ClearFetchedReports')
|
||||||
store.dispatch('FetchReports')
|
store.dispatch('FetchReports')
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
|
@ -50,7 +50,7 @@ describe('Reports filter', () => {
|
||||||
it('shows closed reports when "Closed" filter is applied', async (done) => {
|
it('shows closed reports when "Closed" filter is applied', async (done) => {
|
||||||
expect(store.state.reports.fetchedReports.length).toEqual(7)
|
expect(store.state.reports.fetchedReports.length).toEqual(7)
|
||||||
|
|
||||||
store.dispatch('SetFilter', 'closed')
|
store.dispatch('SetReportsFilter', 'closed')
|
||||||
store.dispatch('ClearFetchedReports')
|
store.dispatch('ClearFetchedReports')
|
||||||
store.dispatch('FetchReports')
|
store.dispatch('FetchReports')
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
|
@ -62,13 +62,13 @@ describe('Reports filter', () => {
|
||||||
it('shows all users after removing filters', async (done) => {
|
it('shows all users after removing filters', async (done) => {
|
||||||
expect(store.state.reports.fetchedReports.length).toEqual(7)
|
expect(store.state.reports.fetchedReports.length).toEqual(7)
|
||||||
|
|
||||||
store.dispatch('SetFilter', 'open')
|
store.dispatch('SetReportsFilter', 'open')
|
||||||
store.dispatch('ClearFetchedReports')
|
store.dispatch('ClearFetchedReports')
|
||||||
store.dispatch('FetchReports')
|
store.dispatch('FetchReports')
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
expect(store.state.reports.fetchedReports.length).toEqual(2)
|
expect(store.state.reports.fetchedReports.length).toEqual(2)
|
||||||
|
|
||||||
store.dispatch('SetFilter', '')
|
store.dispatch('SetReportsFilter', '')
|
||||||
store.dispatch('ClearFetchedReports')
|
store.dispatch('ClearFetchedReports')
|
||||||
store.dispatch('FetchReports')
|
store.dispatch('FetchReports')
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
|
|
Loading…
Reference in a new issue