Merge branch 'feature/fetch-statuses-from-given-instance' into 'develop'

Add statuses page + fetch statuses from given instance

Closes #45

See merge request pleroma/admin-fe!67
This commit is contained in:
Maxim Filippov 2019-11-29 08:57:00 +00:00
commit fed3c93316
10 changed files with 194 additions and 4 deletions

View file

@ -30,6 +30,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added ### Added
- Emoji pack configuration - Emoji pack configuration
- Statuses page: fetch all statuses from a given instance
- Ability to require user's password reset - Ability to require user's password reset
Ability to track admin/moderator actions, a.k.a. "the moderation log" Ability to track admin/moderator actions, a.k.a. "the moderation log"

14
src/api/peers.js Normal file
View file

@ -0,0 +1,14 @@
import request from '@/utils/request'
import { getToken } from '@/utils/auth'
import { baseName } from './utils'
export async function fetchPeers(authHost, token) {
return await request({
baseURL: baseName(authHost),
url: `/api/v1/instance/peers`,
method: 'get',
headers: authHeaders(token)
})
}
const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}

View file

@ -21,4 +21,13 @@ export async function deleteStatus(id, authHost, token) {
}) })
} }
export async function fetchStatusesByInstance(instance, authHost, token, pageSize, page = 1) {
return await request({
baseURL: baseName(authHost),
url: `/api/pleroma/admin/instances/${instance}/statuses?page=${page}&page_size=${pageSize}`,
method: 'get',
headers: authHeaders(token)
})
}
const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {} const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}

View file

@ -232,6 +232,11 @@ export default {
passwordResetTokenCreated: 'Password reset token was created', passwordResetTokenCreated: 'Password reset token was created',
accountCreated: 'New account was created!' accountCreated: 'New account was created!'
}, },
statuses: {
statuses: 'Statuses',
instanceFilter: 'Instance filter',
loadMore: 'Load more'
},
userProfile: { userProfile: {
tags: 'Tags', tags: 'Tags',
moderator: 'Moderator', moderator: 'Moderator',

View file

@ -21,6 +21,20 @@ const settings = {
] ]
} }
const statusesDisabled = disabledFeatures.includes('statuses')
const statuses = {
path: '/statuses',
component: Layout,
children: [
{
path: 'index',
component: () => import('@/views/statuses/index'),
name: 'Statuses',
meta: { title: 'Statuses', icon: 'form', noCache: true }
}
]
}
const reportsDisabled = disabledFeatures.includes('reports') const reportsDisabled = disabledFeatures.includes('reports')
const reports = { const reports = {
path: '/reports', path: '/reports',
@ -126,6 +140,7 @@ export const asyncRouterMap = [
} }
] ]
}, },
...(statusesDisabled ? [] : [statuses]),
...(reportsDisabled ? [] : [reports]), ...(reportsDisabled ? [] : [reports]),
...(invitesDisabled ? [] : [invites]), ...(invitesDisabled ? [] : [invites]),
...(moderationLogDisabled ? [] : [moderationLog]), ...(moderationLogDisabled ? [] : [moderationLog]),

View file

@ -49,6 +49,7 @@ const getters = {
http: state => state.settings.settings['http'], http: state => state.settings.settings['http'],
httpSecurity: state => state.settings.settings['http_security'], httpSecurity: state => state.settings.settings['http_security'],
instance: state => state.settings.settings['instance'], instance: state => state.settings.settings['instance'],
instances: state => state.peers.fetchedPeers,
kocaptcha: state => state.settings.settings['Pleroma.Captcha.Kocaptcha'], kocaptcha: state => state.settings.settings['Pleroma.Captcha.Kocaptcha'],
level: state => state.settings.settings['level'], level: state => state.settings.settings['level'],
ldap: state => state.settings.settings['ldap'], ldap: state => state.settings.settings['ldap'],
@ -82,6 +83,7 @@ const getters = {
richMedia: state => state.settings.settings['rich_media'], richMedia: state => state.settings.settings['rich_media'],
suggestions: state => state.settings.settings['suggestions'], suggestions: state => state.settings.settings['suggestions'],
scheduledActivity: state => state.settings.settings['Pleroma.ScheduledActivity'], scheduledActivity: state => state.settings.settings['Pleroma.ScheduledActivity'],
statuses: state => state.status.fetchedStatuses,
teslaAdapter: state => state.settings.settings['adapter'], teslaAdapter: state => state.settings.settings['adapter'],
twitter: state => state.settings.settings['Ueberauth.Strategy.Twitter.OAuth'], twitter: state => state.settings.settings['Ueberauth.Strategy.Twitter.OAuth'],
ueberauth: state => state.settings.settings['Ueberauth'], ueberauth: state => state.settings.settings['Ueberauth'],

View file

@ -4,6 +4,7 @@ import app from './modules/app'
import errorLog from './modules/errorLog' import errorLog from './modules/errorLog'
import moderationLog from './modules/moderationLog' import moderationLog from './modules/moderationLog'
import invites from './modules/invites' import invites from './modules/invites'
import peers from './modules/peers'
import permission from './modules/permission' import permission from './modules/permission'
import relays from './modules/relays' import relays from './modules/relays'
import reports from './modules/reports' import reports from './modules/reports'
@ -24,6 +25,7 @@ const store = new Vuex.Store({
errorLog, errorLog,
moderationLog, moderationLog,
invites, invites,
peers,
permission, permission,
relays, relays,
reports, reports,

View file

@ -0,0 +1,28 @@
import { fetchPeers } from '@/api/peers'
const peers = {
state: {
fetchedPeers: [],
loading: true
},
mutations: {
SET_PEERS: (state, peers) => {
state.fetchedPeers = peers
},
SET_LOADING: (state, status) => {
state.loading = status
}
},
actions: {
async FetchPeers({ commit, getters }) {
const peers = await fetchPeers(getters.authHost, getters.token)
commit('SET_PEERS', peers.data)
commit('SET_LOADING', false)
}
}
}
export default peers

View file

@ -1,6 +1,21 @@
import { changeStatusScope, deleteStatus } from '@/api/status' import { changeStatusScope, deleteStatus, fetchStatusesByInstance } from '@/api/status'
const status = { const status = {
state: {
fetchedStatuses: [],
loading: false
},
mutations: {
SET_STATUSES: (state, statuses) => {
state.fetchedStatuses = statuses
},
PUSH_STATUSES: (state, statuses) => {
state.fetchedStatuses = [...state.fetchedStatuses, ...statuses]
},
SET_LOADING: (state, status) => {
state.loading = status
}
},
actions: { actions: {
async ChangeStatusScope({ dispatch, getters }, { statusId, isSensitive, visibility, reportCurrentPage, userId, godmode }) { async ChangeStatusScope({ dispatch, getters }, { statusId, isSensitive, visibility, reportCurrentPage, userId, godmode }) {
await changeStatusScope(statusId, isSensitive, visibility, getters.authHost, getters.token) await changeStatusScope(statusId, isSensitive, visibility, getters.authHost, getters.token)
@ -14,13 +29,27 @@ const status = {
}, },
async DeleteStatus({ dispatch, getters }, { statusId, reportCurrentPage, userId, godmode }) { async DeleteStatus({ dispatch, getters }, { statusId, reportCurrentPage, userId, godmode }) {
await deleteStatus(statusId, getters.authHost, getters.token) await deleteStatus(statusId, getters.authHost, getters.token)
if (reportCurrentPage !== 0) { if (reportCurrentPage !== 0) { // called from Reports
dispatch('FetchReports', reportCurrentPage) dispatch('FetchReports', reportCurrentPage)
} else if (userId.length > 0) { } else if (userId.length > 0) { // called from User profile
dispatch('FetchUserStatuses', { userId, godmode }) dispatch('FetchUserStatuses', { userId, godmode })
} else { } else { // called from GroupedReports
dispatch('FetchGroupedReports') dispatch('FetchGroupedReports')
} }
},
async FetchStatusesByInstance({ commit, getters }, { instance, page, pageSize }) {
commit('SET_LOADING', true)
const statuses = await fetchStatusesByInstance(instance, getters.authHost, getters.token, pageSize, page)
commit('SET_STATUSES', statuses.data)
commit('SET_LOADING', false)
},
async FetchStatusesPageByInstance({ commit, getters }, { instance, page, pageSize }) {
commit('SET_LOADING', true)
const statuses = await fetchStatusesByInstance(instance, getters.authHost, getters.token, pageSize, page)
commit('PUSH_STATUSES', statuses.data)
commit('SET_LOADING', false)
} }
} }
} }

View file

@ -0,0 +1,85 @@
<template>
<div v-if="!loadingPeers" class="statuses-container">
<h1>
{{ $t('statuses.statuses') }}
</h1>
<div class="filter-container">
<el-select v-model="selectedInstance" :placeholder="$t('statuses.instanceFilter')" @change="handleFilterChange">
<el-option
v-for="(instance,index) in instances"
:key="index"
:label="instance"
:value="instance"/>
</el-select>
</div>
<status v-for="status in statuses" :key="status.id" :status="status" />
<div v-if="statuses.length > 0" class="statuses-pagination">
<el-button @click="handleLoadMore">{{ $t('statuses.loadMore') }}</el-button>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import Status from '../status/Status'
export default {
name: 'Statuses',
components: {
Status
},
data() {
return {
selectedInstance: '',
page: 1,
pageSize: 2
}
},
computed: {
loadingPeers() {
return this.$store.state.peers.loading
},
...mapGetters([
'instances',
'statuses'
])
},
created() {
},
mounted() {
this.$store.dispatch('FetchPeers')
},
methods: {
handleFilterChange(instance) {
this.page = 1
this.$store.dispatch('FetchStatusesByInstance', { instance, page: this.page, pageSize: this.pageSize })
},
handleLoadMore() {
this.page = this.page + 1
this.$store.dispatch('FetchStatusesPageByInstance', {
instance: this.selectedInstance,
page: this.page,
pageSize: this.pageSize
})
}
}
}
</script>
<style rel='stylesheet/scss' lang='scss'>
.statuses-container {
padding: 0 15px;
}
.filter-container {
margin: 22px 15px 15px 0;
}
.statuses-pagination {
padding: 15px 0;
text-align: center;
}
h1 {
margin: 22px 0 0 0;
}
</style>