mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-12 23:35:58 +00:00
fix(backend): fix statistics and introduce new values (#8550)
* fix statistics and introduce new values * fix locales
This commit is contained in:
parent
4489ae1a89
commit
34c0e5166f
29
backend/src/graphql/queries/statistics.ts
Normal file
29
backend/src/graphql/queries/statistics.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
export const statistics = gql`
|
||||
query statistics {
|
||||
statistics {
|
||||
users
|
||||
usersDeleted
|
||||
posts
|
||||
comments
|
||||
notifications
|
||||
emails
|
||||
follows
|
||||
shouts
|
||||
invites
|
||||
chatMessages
|
||||
chatRooms
|
||||
tags
|
||||
locations
|
||||
groups
|
||||
inviteCodes
|
||||
inviteCodesExpired
|
||||
inviteCodesRedeemed
|
||||
badgesRewarded
|
||||
badgesDisplayed
|
||||
usersVerified
|
||||
reports
|
||||
}
|
||||
}
|
||||
`
|
||||
@ -2,52 +2,39 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
import { ApolloServer } from 'apollo-server-express'
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
import databaseContext from '@context/database'
|
||||
import Factory, { cleanDatabase } from '@db/factories'
|
||||
import { getNeode, getDriver } from '@db/neo4j'
|
||||
import createServer from '@src/server'
|
||||
import { statistics } from '@graphql/queries/statistics'
|
||||
import createServer, { getContext } from '@src/server'
|
||||
|
||||
const database = databaseContext()
|
||||
|
||||
let server: ApolloServer
|
||||
let query, authenticatedUser
|
||||
const instance = getNeode()
|
||||
const driver = getDriver()
|
||||
|
||||
const statisticsQuery = gql`
|
||||
query {
|
||||
statistics {
|
||||
countUsers
|
||||
countPosts
|
||||
countComments
|
||||
countNotifications
|
||||
countInvites
|
||||
countFollows
|
||||
countShouts
|
||||
}
|
||||
}
|
||||
`
|
||||
beforeAll(async () => {
|
||||
await cleanDatabase()
|
||||
|
||||
authenticatedUser = undefined
|
||||
const { server } = createServer({
|
||||
context: () => {
|
||||
return {
|
||||
driver,
|
||||
neode: instance,
|
||||
user: authenticatedUser,
|
||||
}
|
||||
},
|
||||
})
|
||||
query = createTestClient(server).query
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
const contextUser = async (_req) => authenticatedUser
|
||||
const context = getContext({ user: contextUser, database })
|
||||
|
||||
server = createServer({ context }).server
|
||||
|
||||
const createTestClientResult = createTestClient(server)
|
||||
query = createTestClientResult.query
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
await cleanDatabase()
|
||||
await driver.close()
|
||||
void server.stop()
|
||||
void database.driver.close()
|
||||
database.neode.close()
|
||||
})
|
||||
|
||||
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
|
||||
afterEach(async () => {
|
||||
await cleanDatabase()
|
||||
})
|
||||
@ -63,8 +50,8 @@ describe('statistics', () => {
|
||||
})
|
||||
|
||||
it('returns the count of all users', async () => {
|
||||
await expect(query({ query: statisticsQuery })).resolves.toMatchObject({
|
||||
data: { statistics: { countUsers: 6 } },
|
||||
await expect(query({ query: statistics })).resolves.toMatchObject({
|
||||
data: { statistics: { users: 6 } },
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
@ -80,8 +67,8 @@ describe('statistics', () => {
|
||||
})
|
||||
|
||||
it('returns the count of all posts', async () => {
|
||||
await expect(query({ query: statisticsQuery })).resolves.toMatchObject({
|
||||
data: { statistics: { countPosts: 3 } },
|
||||
await expect(query({ query: statistics })).resolves.toMatchObject({
|
||||
data: { statistics: { posts: 3 } },
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
@ -97,8 +84,8 @@ describe('statistics', () => {
|
||||
})
|
||||
|
||||
it('returns the count of all comments', async () => {
|
||||
await expect(query({ query: statisticsQuery })).resolves.toMatchObject({
|
||||
data: { statistics: { countComments: 2 } },
|
||||
await expect(query({ query: statistics })).resolves.toMatchObject({
|
||||
data: { statistics: { comments: 2 } },
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
@ -116,8 +103,8 @@ describe('statistics', () => {
|
||||
})
|
||||
|
||||
it('returns the count of all follows', async () => {
|
||||
await expect(query({ query: statisticsQuery })).resolves.toMatchObject({
|
||||
data: { statistics: { countFollows: 1 } },
|
||||
await expect(query({ query: statistics })).resolves.toMatchObject({
|
||||
data: { statistics: { follows: 1 } },
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
@ -143,8 +130,8 @@ describe('statistics', () => {
|
||||
})
|
||||
|
||||
it('returns the count of all shouts', async () => {
|
||||
await expect(query({ query: statisticsQuery })).resolves.toMatchObject({
|
||||
data: { statistics: { countShouts: 2 } },
|
||||
await expect(query({ query: statistics })).resolves.toMatchObject({
|
||||
data: { statistics: { shouts: 2 } },
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,48 +1,83 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
/* eslint-disable security/detect-object-injection */
|
||||
/* eslint-disable @typescript-eslint/dot-notation */
|
||||
import { Context } from '@src/server'
|
||||
|
||||
export default {
|
||||
Query: {
|
||||
statistics: async (_parent, _args, { driver }) => {
|
||||
const session = driver.session()
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const counts: any = {}
|
||||
try {
|
||||
const mapping = {
|
||||
countUsers: 'User',
|
||||
countPosts: 'Post',
|
||||
countComments: 'Comment',
|
||||
countNotifications: 'NOTIFIED',
|
||||
countEmails: 'EmailAddress',
|
||||
countFollows: 'FOLLOWS',
|
||||
countShouts: 'SHOUTED',
|
||||
}
|
||||
const statisticsReadTxResultPromise = session.readTransaction(async (transaction) => {
|
||||
const statisticsTransactionResponse = await transaction.run(
|
||||
`
|
||||
CALL apoc.meta.stats() YIELD labels, relTypesCount
|
||||
RETURN labels, relTypesCount
|
||||
`,
|
||||
)
|
||||
return statisticsTransactionResponse.records.map((record) => {
|
||||
return {
|
||||
...record.get('labels'),
|
||||
...record.get('relTypesCount'),
|
||||
}
|
||||
})
|
||||
})
|
||||
const [statistics] = await statisticsReadTxResultPromise
|
||||
Object.keys(mapping).forEach((key) => {
|
||||
const stat = statistics[mapping[key]]
|
||||
counts[key] = stat ? stat.toNumber() : 0
|
||||
})
|
||||
counts.countInvites = counts.countEmails - counts.countUsers
|
||||
return counts
|
||||
} finally {
|
||||
session.close()
|
||||
statistics: async (_parent, _args, context: Context) => {
|
||||
const statistics = {
|
||||
users: 0,
|
||||
usersDeleted: 0,
|
||||
posts: 0,
|
||||
comments: 0,
|
||||
notifications: 0,
|
||||
emails: 0,
|
||||
follows: 0,
|
||||
shouts: 0,
|
||||
invites: 0,
|
||||
chatMessages: 0,
|
||||
chatRooms: 0,
|
||||
tags: 0,
|
||||
locations: 0,
|
||||
groups: 0,
|
||||
inviteCodes: 0,
|
||||
inviteCodesExpired: 0,
|
||||
inviteCodesRedeemed: 0,
|
||||
badgesRewarded: 0,
|
||||
badgesDisplayed: 0,
|
||||
usersVerified: 0,
|
||||
reports: 0,
|
||||
}
|
||||
const [metaStats] = (
|
||||
await context.database.query({
|
||||
query: `CALL apoc.meta.stats() YIELD labels, relTypesCount
|
||||
RETURN labels, relTypesCount`,
|
||||
})
|
||||
).records.map((record) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
return { ...record.get('labels'), ...record.get('relTypesCount') }
|
||||
})
|
||||
|
||||
const deletedUsers = parseInt(
|
||||
(
|
||||
await context.database.query({
|
||||
query: `MATCH (u:User) WHERE NOT (u)-[:PRIMARY_EMAIL]->(:EmailAddress) RETURN toString(count(u)) AS count`,
|
||||
})
|
||||
).records[0].get('count') as string,
|
||||
)
|
||||
|
||||
const invalidInviteCodes = parseInt(
|
||||
(
|
||||
await context.database.query({
|
||||
query: `MATCH (i:InviteCode) WHERE NOT i.expiresAt IS NULL OR i.expiresAt >= datetime() RETURN toString(count(i)) AS count`,
|
||||
})
|
||||
).records[0].get('count') as string,
|
||||
)
|
||||
|
||||
statistics.users = (metaStats['User']?.toNumber() ?? 0) - deletedUsers
|
||||
statistics.usersDeleted = deletedUsers
|
||||
statistics.posts = metaStats['Post']?.toNumber() ?? 0
|
||||
statistics.comments = metaStats['Comment']?.toNumber() ?? 0
|
||||
statistics.notifications = metaStats['NOTIFIED']?.toNumber() ?? 0
|
||||
statistics.emails = metaStats['EmailAddress']?.toNumber() ?? 0
|
||||
statistics.follows = metaStats['FOLLOWS']?.toNumber() ?? 0
|
||||
statistics.shouts = metaStats['SHOUTED']?.toNumber() ?? 0
|
||||
statistics.invites = statistics.emails - statistics.users
|
||||
statistics.chatMessages = metaStats['Message']?.toNumber() ?? 0
|
||||
statistics.chatRooms = metaStats['Room']?.toNumber() ?? 0
|
||||
statistics.tags = metaStats['Tag']?.toNumber() ?? 0
|
||||
statistics.locations = metaStats['Location']?.toNumber() ?? 0
|
||||
statistics.groups = metaStats['Group']?.toNumber() ?? 0
|
||||
statistics.inviteCodes = (metaStats['InviteCode']?.toNumber() ?? 0) - invalidInviteCodes
|
||||
statistics.inviteCodesExpired = invalidInviteCodes
|
||||
statistics.inviteCodesRedeemed = metaStats['REDEEMED']?.toNumber() ?? 0
|
||||
statistics.badgesRewarded = metaStats['REWARDED']?.toNumber() ?? 0
|
||||
statistics.badgesDisplayed = metaStats['SELECTED']?.toNumber() ?? 0
|
||||
statistics.usersVerified = metaStats['VERIFIES']?.toNumber() ?? 0
|
||||
statistics.reports = metaStats['InviteCode']?.toNumber() ?? 0
|
||||
return statistics
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -3,12 +3,26 @@ type Query {
|
||||
}
|
||||
|
||||
type Statistics {
|
||||
countUsers: Int!
|
||||
countPosts: Int!
|
||||
countComments: Int!
|
||||
countNotifications: Int!
|
||||
countInvites: Int!
|
||||
countFollows: Int!
|
||||
countShouts: Int!
|
||||
users: Int!
|
||||
usersDeleted: Int!
|
||||
posts: Int!
|
||||
comments: Int!
|
||||
notifications: Int!
|
||||
emails: Int!
|
||||
follows: Int!
|
||||
shouts: Int!
|
||||
invites: Int!
|
||||
chatMessages: Int!
|
||||
chatRooms: Int!
|
||||
tags: Int!
|
||||
locations: Int!
|
||||
groups: Int!
|
||||
inviteCodes: Int!
|
||||
inviteCodesExpired: Int!
|
||||
inviteCodesRedeemed: Int!
|
||||
badgesRewarded: Int!
|
||||
badgesDisplayed: Int!
|
||||
usersVerified: Int!
|
||||
reports: Int!
|
||||
}
|
||||
|
||||
|
||||
@ -3,13 +3,27 @@ import gql from 'graphql-tag'
|
||||
export const Statistics = gql`
|
||||
query {
|
||||
statistics {
|
||||
countUsers
|
||||
countPosts
|
||||
countComments
|
||||
countNotifications
|
||||
countInvites
|
||||
countFollows
|
||||
countShouts
|
||||
users
|
||||
usersDeleted
|
||||
posts
|
||||
comments
|
||||
notifications
|
||||
emails
|
||||
follows
|
||||
shouts
|
||||
invites
|
||||
chatMessages
|
||||
chatRooms
|
||||
tags
|
||||
locations
|
||||
groups
|
||||
inviteCodes
|
||||
inviteCodesExpired
|
||||
inviteCodesRedeemed
|
||||
badgesRewarded
|
||||
badgesDisplayed
|
||||
usersVerified
|
||||
reports
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
@ -39,16 +39,28 @@
|
||||
"postCount": "Beiträge"
|
||||
},
|
||||
"dashboard": {
|
||||
"badgesDisplayed": "Badges ausgestellt",
|
||||
"badgesRewarded": "Badges verteilt",
|
||||
"chatMessages": "Chat-Nachrichten",
|
||||
"chatRooms": "Chat-Räume",
|
||||
"comments": "Kommentare",
|
||||
"follows": "Folgen",
|
||||
"emails": "E-Mails",
|
||||
"follows": "Follows",
|
||||
"groups": "Gruppen",
|
||||
"inviteCodes": "Einladungslinks",
|
||||
"inviteCodesExpired": "Abgelaufene Einladungslinks",
|
||||
"inviteCodesRedeemed": "Eingelöste Einladungslinks",
|
||||
"invites": "Einladungen",
|
||||
"locations": "Orte",
|
||||
"name": "Startzentrale",
|
||||
"notifications": "Benachrichtigungen",
|
||||
"organizations": "Organisationen",
|
||||
"posts": "Beiträge",
|
||||
"projects": "Projekte",
|
||||
"reports": "Gemeldet",
|
||||
"shouts": "Empfehlungen",
|
||||
"users": "Nutzer"
|
||||
"tags": "Tags",
|
||||
"users": "Nutzer",
|
||||
"usersDeleted": "Gelöschte Nutzer",
|
||||
"usersVerified": "Verifizierte Nutzer"
|
||||
},
|
||||
"donations": {
|
||||
"goal": "Monatlich benötigte Spenden",
|
||||
|
||||
@ -39,16 +39,28 @@
|
||||
"postCount": "Posts"
|
||||
},
|
||||
"dashboard": {
|
||||
"badgesDisplayed": "Badges Displayed",
|
||||
"badgesRewarded": "Badges Rewarded",
|
||||
"chatMessages": "Chat Messages",
|
||||
"chatRooms": "Chat Rooms",
|
||||
"comments": "Comments",
|
||||
"emails": "E-Mails",
|
||||
"follows": "Follows",
|
||||
"groups": "Groups",
|
||||
"inviteCodes": "Invite Codes",
|
||||
"inviteCodesExpired": "Expired Invite Codes",
|
||||
"inviteCodesRedeemed": "Redeemed Invite Codes",
|
||||
"invites": "Invites",
|
||||
"locations": "Locations",
|
||||
"name": "Dashboard",
|
||||
"notifications": "Notifications",
|
||||
"organizations": "Organizations",
|
||||
"posts": "Posts",
|
||||
"projects": "Projects",
|
||||
"reports": "Reports",
|
||||
"shouts": "Shouts",
|
||||
"users": "Users"
|
||||
"tags": "Tags",
|
||||
"users": "Users",
|
||||
"usersDeleted": "Users deleted",
|
||||
"usersVerified": "Users verified"
|
||||
},
|
||||
"donations": {
|
||||
"goal": "Monthly donations needed",
|
||||
|
||||
@ -39,16 +39,28 @@
|
||||
"postCount": "Contribuciones"
|
||||
},
|
||||
"dashboard": {
|
||||
"badgesDisplayed": null,
|
||||
"badgesRewarded": null,
|
||||
"chatMessages": null,
|
||||
"chatRooms": null,
|
||||
"comments": "Comentarios",
|
||||
"emails": null,
|
||||
"follows": "Sigue",
|
||||
"groups": null,
|
||||
"inviteCodes": null,
|
||||
"inviteCodesExpired": null,
|
||||
"inviteCodesRedeemed": null,
|
||||
"invites": "Invita",
|
||||
"locations": null,
|
||||
"name": "Tablero",
|
||||
"notifications": "Notificaciones",
|
||||
"organizations": "Organizaciones",
|
||||
"posts": "Contribuciones",
|
||||
"projects": "Proyectos",
|
||||
"reports": null,
|
||||
"shouts": "Recomendaciones",
|
||||
"users": "Usuarios"
|
||||
"tags": null,
|
||||
"users": "Usuarios",
|
||||
"usersDeleted": null,
|
||||
"usersVerified": null
|
||||
},
|
||||
"donations": {
|
||||
"goal": "Donaciones mensuales necesarias",
|
||||
|
||||
@ -39,16 +39,28 @@
|
||||
"postCount": "Postes"
|
||||
},
|
||||
"dashboard": {
|
||||
"badgesDisplayed": null,
|
||||
"badgesRewarded": null,
|
||||
"chatMessages": null,
|
||||
"chatRooms": null,
|
||||
"comments": "Commentaires",
|
||||
"emails": null,
|
||||
"follows": "Suit",
|
||||
"groups": null,
|
||||
"inviteCodes": null,
|
||||
"inviteCodesExpired": null,
|
||||
"inviteCodesRedeemed": null,
|
||||
"invites": "Invitations",
|
||||
"locations": null,
|
||||
"name": "Tableau de bord",
|
||||
"notifications": "Notifications",
|
||||
"organizations": "Organisations",
|
||||
"posts": "Postes",
|
||||
"projects": "Projets",
|
||||
"reports": null,
|
||||
"shouts": "Cris",
|
||||
"users": "Utilisateurs"
|
||||
"tags": null,
|
||||
"users": "Utilisateurs",
|
||||
"usersDeleted": null,
|
||||
"usersVerified": null
|
||||
},
|
||||
"donations": {
|
||||
"goal": "Dons mensuels requis",
|
||||
|
||||
@ -39,16 +39,28 @@
|
||||
"postCount": "Messaggi"
|
||||
},
|
||||
"dashboard": {
|
||||
"badgesDisplayed": null,
|
||||
"badgesRewarded": null,
|
||||
"chatMessages": null,
|
||||
"chatRooms": null,
|
||||
"comments": "Commenti",
|
||||
"emails": null,
|
||||
"follows": "Segue",
|
||||
"groups": null,
|
||||
"inviteCodes": null,
|
||||
"inviteCodesExpired": null,
|
||||
"inviteCodesRedeemed": null,
|
||||
"invites": "Inviti",
|
||||
"locations": null,
|
||||
"name": "Cruscotto",
|
||||
"notifications": "Notifiche",
|
||||
"organizations": "Organizzazioni",
|
||||
"posts": "Messaggi",
|
||||
"projects": "Progetti",
|
||||
"reports": null,
|
||||
"shouts": "Gridi",
|
||||
"users": "Utenti"
|
||||
"tags": null,
|
||||
"users": "Utenti",
|
||||
"usersDeleted": null,
|
||||
"usersVerified": null
|
||||
},
|
||||
"donations": {
|
||||
"goal": "Donazioni mensili necessarie",
|
||||
|
||||
@ -39,16 +39,28 @@
|
||||
"postCount": "Berichten"
|
||||
},
|
||||
"dashboard": {
|
||||
"badgesDisplayed": null,
|
||||
"badgesRewarded": null,
|
||||
"chatMessages": null,
|
||||
"chatRooms": null,
|
||||
"comments": "Opmerkingen",
|
||||
"emails": null,
|
||||
"follows": "Volgt",
|
||||
"groups": null,
|
||||
"inviteCodes": null,
|
||||
"inviteCodesExpired": null,
|
||||
"inviteCodesRedeemed": null,
|
||||
"invites": "Uitnodigingen",
|
||||
"locations": null,
|
||||
"name": "Dashboard",
|
||||
"notifications": "Meldingen",
|
||||
"organizations": "Organisaties",
|
||||
"posts": "Berichten",
|
||||
"projects": "Projecten",
|
||||
"reports": null,
|
||||
"shouts": "Shouts",
|
||||
"users": "Gebruikers"
|
||||
"tags": null,
|
||||
"users": "Gebruikers",
|
||||
"usersDeleted": null,
|
||||
"usersVerified": null
|
||||
},
|
||||
"donations": {
|
||||
"goal": null,
|
||||
|
||||
@ -39,16 +39,28 @@
|
||||
"postCount": "Stanowiska"
|
||||
},
|
||||
"dashboard": {
|
||||
"badgesDisplayed": null,
|
||||
"badgesRewarded": null,
|
||||
"chatMessages": null,
|
||||
"chatRooms": null,
|
||||
"comments": "Komentarze",
|
||||
"emails": null,
|
||||
"follows": "Podąża za",
|
||||
"groups": null,
|
||||
"inviteCodes": null,
|
||||
"inviteCodesExpired": null,
|
||||
"inviteCodesRedeemed": null,
|
||||
"invites": "Zaprasza",
|
||||
"locations": null,
|
||||
"name": "Tablica rozdzielcza",
|
||||
"notifications": "Powiadomienia",
|
||||
"organizations": "Organizacje",
|
||||
"posts": "Stanowiska",
|
||||
"projects": "Projekty",
|
||||
"reports": null,
|
||||
"shouts": "Zalecane",
|
||||
"users": "Użytkownicy"
|
||||
"tags": null,
|
||||
"users": "Użytkownicy",
|
||||
"usersDeleted": null,
|
||||
"usersVerified": null
|
||||
},
|
||||
"donations": {
|
||||
"goal": null,
|
||||
|
||||
@ -39,16 +39,28 @@
|
||||
"postCount": "Postagens"
|
||||
},
|
||||
"dashboard": {
|
||||
"badgesDisplayed": null,
|
||||
"badgesRewarded": null,
|
||||
"chatMessages": null,
|
||||
"chatRooms": null,
|
||||
"comments": "Comentários",
|
||||
"emails": null,
|
||||
"follows": "Segue",
|
||||
"groups": null,
|
||||
"inviteCodes": null,
|
||||
"inviteCodesExpired": null,
|
||||
"inviteCodesRedeemed": null,
|
||||
"invites": "Convites",
|
||||
"locations": null,
|
||||
"name": "Painel de controle",
|
||||
"notifications": "Notificações",
|
||||
"organizations": "Organizações",
|
||||
"posts": "Postagens",
|
||||
"projects": "Projetos",
|
||||
"reports": null,
|
||||
"shouts": "Aclamações",
|
||||
"users": "Usuários"
|
||||
"tags": null,
|
||||
"users": "Usuários",
|
||||
"usersDeleted": null,
|
||||
"usersVerified": null
|
||||
},
|
||||
"donations": {
|
||||
"goal": "Doações mensais necessárias",
|
||||
|
||||
@ -39,16 +39,28 @@
|
||||
"postCount": "Посты"
|
||||
},
|
||||
"dashboard": {
|
||||
"badgesDisplayed": null,
|
||||
"badgesRewarded": null,
|
||||
"chatMessages": null,
|
||||
"chatRooms": null,
|
||||
"comments": "Комментарии",
|
||||
"emails": null,
|
||||
"follows": "Подписки",
|
||||
"groups": null,
|
||||
"inviteCodes": null,
|
||||
"inviteCodesExpired": null,
|
||||
"inviteCodesRedeemed": null,
|
||||
"invites": "Приглашения",
|
||||
"locations": null,
|
||||
"name": "Панель управления",
|
||||
"notifications": "Уведомления",
|
||||
"organizations": "Организации",
|
||||
"posts": "Посты",
|
||||
"projects": "Проекты",
|
||||
"reports": null,
|
||||
"shouts": "Выкрики",
|
||||
"users": "Пользователи"
|
||||
"tags": null,
|
||||
"users": "Пользователи",
|
||||
"usersDeleted": null,
|
||||
"usersVerified": null
|
||||
},
|
||||
"donations": {
|
||||
"goal": "Необходимы ежемесячные пожертвования",
|
||||
|
||||
@ -20,100 +20,20 @@
|
||||
<template v-else-if="data">
|
||||
<ds-space margin="large">
|
||||
<ds-flex>
|
||||
<ds-flex-item :width="{ base: '100%', sm: '50%', md: '33%' }">
|
||||
<ds-flex-item
|
||||
v-for="(value, name, index) in filterStatistics(data.statistics)"
|
||||
:key="index"
|
||||
:width="{ base: '100%', sm: '50%', md: '33%' }"
|
||||
>
|
||||
<ds-space margin="small">
|
||||
<ds-number
|
||||
:count="0"
|
||||
:label="$t('admin.dashboard.users')"
|
||||
:label="$t('admin.dashboard.' + name)"
|
||||
size="x-large"
|
||||
uppercase
|
||||
>
|
||||
<client-only slot="count">
|
||||
<hc-count-to :end-val="data.statistics.countUsers" />
|
||||
</client-only>
|
||||
</ds-number>
|
||||
</ds-space>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item :width="{ base: '100%', sm: '50%', md: '33%' }">
|
||||
<ds-space margin="small">
|
||||
<ds-number
|
||||
:count="0"
|
||||
:label="$t('admin.dashboard.posts')"
|
||||
size="x-large"
|
||||
uppercase
|
||||
>
|
||||
<client-only slot="count">
|
||||
<hc-count-to :end-val="data.statistics.countPosts" />
|
||||
</client-only>
|
||||
</ds-number>
|
||||
</ds-space>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item :width="{ base: '100%', sm: '50%', md: '33%' }">
|
||||
<ds-space margin="small">
|
||||
<ds-number
|
||||
:count="0"
|
||||
:label="$t('admin.dashboard.comments')"
|
||||
size="x-large"
|
||||
uppercase
|
||||
>
|
||||
<client-only slot="count">
|
||||
<hc-count-to :end-val="data.statistics.countComments" />
|
||||
</client-only>
|
||||
</ds-number>
|
||||
</ds-space>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item :width="{ base: '100%', sm: '50%', md: '33%' }">
|
||||
<ds-space margin="small">
|
||||
<ds-number
|
||||
:count="0"
|
||||
:label="$t('admin.dashboard.notifications')"
|
||||
size="x-large"
|
||||
uppercase
|
||||
>
|
||||
<client-only slot="count">
|
||||
<hc-count-to :end-val="data.statistics.countNotifications" />
|
||||
</client-only>
|
||||
</ds-number>
|
||||
</ds-space>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item :width="{ base: '100%', sm: '50%', md: '33%' }">
|
||||
<ds-space margin="small">
|
||||
<ds-number
|
||||
:count="0"
|
||||
:label="$t('admin.dashboard.invites')"
|
||||
size="x-large"
|
||||
uppercase
|
||||
>
|
||||
<client-only slot="count">
|
||||
<hc-count-to :end-val="data.statistics.countInvites" />
|
||||
</client-only>
|
||||
</ds-number>
|
||||
</ds-space>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item :width="{ base: '100%', sm: '50%', md: '33%' }">
|
||||
<ds-space margin="small">
|
||||
<ds-number
|
||||
:count="0"
|
||||
:label="$t('admin.dashboard.follows')"
|
||||
size="x-large"
|
||||
uppercase
|
||||
>
|
||||
<client-only slot="count">
|
||||
<hc-count-to :end-val="data.statistics.countFollows" />
|
||||
</client-only>
|
||||
</ds-number>
|
||||
</ds-space>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item :width="{ base: '100%', sm: '50%', md: '33%' }">
|
||||
<ds-space margin="small">
|
||||
<ds-number
|
||||
:count="0"
|
||||
:label="$t('admin.dashboard.shouts')"
|
||||
size="x-large"
|
||||
uppercase
|
||||
>
|
||||
<client-only slot="count">
|
||||
<hc-count-to :end-val="data.statistics.countShouts" />
|
||||
<hc-count-to :end-val="value" />
|
||||
</client-only>
|
||||
</ds-number>
|
||||
</ds-space>
|
||||
@ -140,5 +60,11 @@ export default {
|
||||
Statistics,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
filterStatistics(data) {
|
||||
delete data.__typename
|
||||
return data
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user