Fetch inbox data

This commit is contained in:
wvffle 2022-07-21 21:20:10 +00:00 committed by Georg Krause
parent 9d8465c950
commit 6b179885ce
4 changed files with 99 additions and 86 deletions

View File

@ -96,12 +96,18 @@ const moderationNotifications = computed(() =>
onMounted(async () => {
if (store.state.auth.authenticated) {
const [edits, reports, requests] = await Promise.all([
const [inbox, edits, reports, requests] = await Promise.all([
axios.get('federation/inbox/', { params: { is_read: false } }).catch(() => ({ data: { count: 0 } })),
axios.get('mutations/', { params: { page_size: 1, q: 'is_approved:null' } }).catch(() => ({ data: { count: 0 } })),
axios.get('manage/moderation/reports/', { params: { page_size: 1, q: 'resolved:no' } }).catch(() => ({ data: { count: 0 } })),
axios.get('manage/moderation/requests/', { params: { page_size: 1, q: 'status:pending' } }).catch(() => ({ data: { count: 0 } }))
])
store.commit('ui/incrementNotifications', {
type: 'inbox',
value: inbox.data.count
})
store.commit('ui/incrementNotifications', {
type: 'pendingReviewEdits',
value: edits.data.count

View File

@ -1,10 +1,83 @@
<script setup lang="ts">
import type { BackendError } from '~/types'
import { ref, reactive, computed, onMounted } from 'vue'
import { useGettext } from 'vue3-gettext'
import { useStore } from '~/store'
import PasswordInput from '~/components/forms/PasswordInput.vue'
interface Props {
next?: string
buttonClasses?: string
showSignup?: boolean
}
const props = withDefaults(defineProps<Props>(), {
next: '/library',
buttonClasses: 'success',
showSignup: true
})
const domain = location.hostname
const { $pgettext } = useGettext()
const store = useStore()
const credentials = reactive({
username: '',
password: ''
})
const labels = computed(() => ({
usernamePlaceholder: $pgettext('Content/Login/Input.Placeholder', 'Enter your username or e-mail address')
}))
const username = ref()
onMounted(() => username.value.focus())
const isLoading = ref(false)
const errors = ref([] as string[])
const submit = async () => {
isLoading.value = true
try {
if (domain === store.getters['instance/domain']) {
await store.dispatch('auth/login', {
credentials,
next: props.next
})
} else {
await store.dispatch('auth/oauthLogin', props.next)
}
} catch (error) {
const backendError = error as BackendError
if (backendError.response?.status === 400) {
errors.value = ['invalid_credentials']
} else {
errors.value = backendError.backendErrors
}
}
isLoading.value = false
}
// export default {
// created () {
// if (this.$store.state.auth.authenticated) {
// this.$router.push(this.next)
// }
// },
// }
</script>
<template>
<form
class="ui form"
@submit.prevent="submit()"
>
<div
v-if="error"
v-if="errors.length > 0"
role="alert"
class="ui negative message"
>
@ -14,18 +87,18 @@
</translate>
</h4>
<ul class="list">
<li v-if="error == 'invalid_credentials' && $store.state.instance.settings.moderation.signup_approval_enabled.value">
<li v-if="errors[0] == 'invalid_credentials' && $store.state.instance.settings.moderation.signup_approval_enabled.value">
<translate translate-context="Content/Login/Error message.List item/Call to action">
If you signed-up recently, you may need to wait before our moderation team review your account, or verify your e-mail address.
</translate>
</li>
<li v-else-if="error == 'invalid_credentials'">
<li v-else-if="errors[0] == 'invalid_credentials'">
<translate translate-context="Content/Login/Error message.List item/Call to action">
Please double-check that your username and password combination is correct and make sure you verified your e-mail address.
</translate>
</li>
<li v-else>
{{ error }}
{{ errors[0] }}
</li>
</ul>
</div>
@ -88,82 +161,3 @@
</button>
</form>
</template>
<script>
import PasswordInput from '~/components/forms/PasswordInput.vue'
export default {
components: {
PasswordInput
},
props: {
next: { type: String, default: '/library' },
buttonClasses: { type: String, default: 'success' },
showSignup: { type: Boolean, default: true }
},
data () {
return {
// We need to initialize the component with any
// properties that will be used in it
credentials: {
username: '',
password: ''
},
error: '',
isLoading: false,
domain: location.hostname
}
},
computed: {
labels () {
const usernamePlaceholder = this.$pgettext('Content/Login/Input.Placeholder', 'Enter your username or e-mail address')
return {
usernamePlaceholder
}
}
},
created () {
if (this.$store.state.auth.authenticated) {
this.$router.push(this.next)
}
},
mounted () {
if (this.$refs.username) {
this.$refs.username.focus()
}
},
methods: {
async submit () {
if (location.hostname === this.$store.getters['instance/domain']) {
return await this.submitSession()
} else {
this.isLoading = true
await this.$store.dispatch('auth/oauthLogin', this.next)
}
},
async submitSession () {
this.isLoading = true
this.error = ''
const credentials = {
username: this.credentials.username,
password: this.credentials.password
}
this.$store
.dispatch('auth/login', {
credentials,
next: this.next,
onError: error => {
if (error.response.status === 400) {
self.error = 'invalid_credentials'
} else {
self.error = error.backendErrors[0]
}
}
})
.then(() => {
self.isLoading = false
})
}
}
}
</script>

View File

@ -1,5 +1,5 @@
import type { NavigationGuardNext, RouteLocationNormalized } from 'vue-router'
import type { NavigationGuardNext, RouteLocationNamedRaw, RouteLocationNormalized } from 'vue-router'
import type { Permission } from '~/store/auth'
import store from '~/store'
@ -12,3 +12,13 @@ export const hasPermissions = (permission: Permission) => (to: RouteLocationNorm
console.log('Not authenticated. Redirecting to library.')
next({ name: 'library.index' })
}
export const requireLoggedIn = (fallbackLocation: RouteLocationNamedRaw) => (to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) => {
if (store.state.auth.authenticated) return next()
return next(fallbackLocation)
}
export const requireLoggedOut = (fallbackLocation: RouteLocationNamedRaw) => (to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) => {
if (!store.state.auth.authenticated) return next()
return next(fallbackLocation)
}

View File

@ -1,12 +1,15 @@
import type { RouteRecordRaw } from 'vue-router'
import { requireLoggedOut } from '../guards'
export default [
{
path: '/login',
name: 'login',
component: () => import('~/views/auth/Login.vue'),
// TODO (wvffle): Use named routes EVERYWHERE
props: route => ({ next: route.query.next || '/library' })
props: route => ({ next: route.query.next || '/library' }),
beforeEnter: requireLoggedOut({ name: 'library.index' })
},
{
path: '/auth/password/reset',