mirror of
https://github.com/IT4Change/gradido.git
synced 2026-02-06 09:56:05 +00:00
Merge branch 'master' into yarn_workspaces_turbo
This commit is contained in:
commit
04514aa375
@ -26,7 +26,7 @@ function getUsersPage(page: number, limit: number): Promise<[User[], number]> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param client
|
* @param client
|
||||||
* @returns user map indices with email
|
* @returns user map indices with username
|
||||||
*/
|
*/
|
||||||
async function loadUsersFromHumHub(client: HumHubClient): Promise<Map<string, GetUser>> {
|
async function loadUsersFromHumHub(client: HumHubClient): Promise<Map<string, GetUser>> {
|
||||||
const start = new Date().getTime()
|
const start = new Date().getTime()
|
||||||
@ -42,7 +42,7 @@ async function loadUsersFromHumHub(client: HumHubClient): Promise<Map<string, Ge
|
|||||||
usersPage.results.forEach((user) => {
|
usersPage.results.forEach((user) => {
|
||||||
// deleted users have empty emails
|
// deleted users have empty emails
|
||||||
if (user.account.email) {
|
if (user.account.email) {
|
||||||
humhubUsers.set(user.account.email.trim(), user)
|
humhubUsers.set(user.account.username, user)
|
||||||
} else {
|
} else {
|
||||||
skippedUsersCount++
|
skippedUsersCount++
|
||||||
}
|
}
|
||||||
@ -52,6 +52,7 @@ async function loadUsersFromHumHub(client: HumHubClient): Promise<Map<string, Ge
|
|||||||
`load users from humhub: ${humhubUsers.size}/${usersPage.total}, skipped: ${skippedUsersCount}\r`,
|
`load users from humhub: ${humhubUsers.size}/${usersPage.total}, skipped: ${skippedUsersCount}\r`,
|
||||||
)
|
)
|
||||||
} while (usersPage && usersPage.results.length === HUMHUB_BULK_SIZE)
|
} while (usersPage && usersPage.results.length === HUMHUB_BULK_SIZE)
|
||||||
|
process.stdout.write('\n')
|
||||||
|
|
||||||
const elapsed = new Date().getTime() - start
|
const elapsed = new Date().getTime() - start
|
||||||
logger.info('load users from humhub', {
|
logger.info('load users from humhub', {
|
||||||
@ -87,23 +88,29 @@ async function main() {
|
|||||||
const humhubUsers = await loadUsersFromHumHub(humHubClient)
|
const humhubUsers = await loadUsersFromHumHub(humHubClient)
|
||||||
|
|
||||||
let dbUserCount = 0
|
let dbUserCount = 0
|
||||||
const executedHumhubActionsCount = [0, 0, 0, 0]
|
const executedHumhubActionsCount = [0, 0, 0, 0, 0]
|
||||||
|
|
||||||
do {
|
do {
|
||||||
const [users, totalUsers] = await getUsersPage(page, USER_BULK_SIZE)
|
try {
|
||||||
dbUserCount += users.length
|
const [users, totalUsers] = await getUsersPage(page, USER_BULK_SIZE)
|
||||||
userCount = users.length
|
dbUserCount += users.length
|
||||||
page++
|
userCount = users.length
|
||||||
const promises: Promise<ExecutedHumhubAction>[] = []
|
page++
|
||||||
users.forEach((user: User) => promises.push(syncUser(user, humhubUsers)))
|
const promises: Promise<ExecutedHumhubAction>[] = []
|
||||||
const executedActions = await Promise.all(promises)
|
users.forEach((user: User) => promises.push(syncUser(user, humhubUsers)))
|
||||||
executedActions.forEach((executedAction: ExecutedHumhubAction) => {
|
const executedActions = await Promise.all(promises)
|
||||||
executedHumhubActionsCount[executedAction as number]++
|
executedActions.forEach((executedAction: ExecutedHumhubAction) => {
|
||||||
})
|
executedHumhubActionsCount[executedAction as number]++
|
||||||
// using process.stdout.write here so that carriage-return is working analog to c
|
})
|
||||||
// printf("\rchecked user: %d/%d", dbUserCount, totalUsers);
|
// using process.stdout.write here so that carriage-return is working analog to c
|
||||||
process.stdout.write(`checked user: ${dbUserCount}/${totalUsers}\r`)
|
// printf("\rchecked user: %d/%d", dbUserCount, totalUsers);
|
||||||
|
process.stdout.write(`checked user: ${dbUserCount}/${totalUsers}\r`)
|
||||||
|
} catch (e) {
|
||||||
|
process.stdout.write('\n')
|
||||||
|
throw e
|
||||||
|
}
|
||||||
} while (userCount === USER_BULK_SIZE)
|
} while (userCount === USER_BULK_SIZE)
|
||||||
|
process.stdout.write('\n')
|
||||||
|
|
||||||
await con.destroy()
|
await con.destroy()
|
||||||
const elapsed = new Date().getTime() - start
|
const elapsed = new Date().getTime() - start
|
||||||
@ -114,12 +121,13 @@ async function main() {
|
|||||||
updatedCount: executedHumhubActionsCount[ExecutedHumhubAction.UPDATE],
|
updatedCount: executedHumhubActionsCount[ExecutedHumhubAction.UPDATE],
|
||||||
skippedCount: executedHumhubActionsCount[ExecutedHumhubAction.SKIP],
|
skippedCount: executedHumhubActionsCount[ExecutedHumhubAction.SKIP],
|
||||||
deletedCount: executedHumhubActionsCount[ExecutedHumhubAction.DELETE],
|
deletedCount: executedHumhubActionsCount[ExecutedHumhubAction.DELETE],
|
||||||
|
validationErrorCount: executedHumhubActionsCount[ExecutedHumhubAction.VALIDATION_ERROR],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
main().catch((e) => {
|
main().catch((e) => {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error(e)
|
console.error(JSON.stringify(e, null, 2))
|
||||||
// eslint-disable-next-line n/no-process-exit
|
// eslint-disable-next-line n/no-process-exit
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
})
|
})
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { User } from 'database'
|
|||||||
|
|
||||||
import { isHumhubUserIdenticalToDbUser } from '@/apis/humhub/compareHumhubUserDbUser'
|
import { isHumhubUserIdenticalToDbUser } from '@/apis/humhub/compareHumhubUserDbUser'
|
||||||
import { GetUser } from '@/apis/humhub/model/GetUser'
|
import { GetUser } from '@/apis/humhub/model/GetUser'
|
||||||
|
import { PostUser } from '@/apis/humhub/model/PostUser'
|
||||||
|
|
||||||
export enum ExecutedHumhubAction {
|
export enum ExecutedHumhubAction {
|
||||||
UPDATE,
|
UPDATE,
|
||||||
@ -26,7 +27,8 @@ export async function syncUser(
|
|||||||
user: User,
|
user: User,
|
||||||
humhubUsers: Map<string, GetUser>,
|
humhubUsers: Map<string, GetUser>,
|
||||||
): Promise<ExecutedHumhubAction> {
|
): Promise<ExecutedHumhubAction> {
|
||||||
const humhubUser = humhubUsers.get(user.emailContact.email.trim())
|
const postUser = new PostUser(user)
|
||||||
|
const humhubUser = humhubUsers.get(postUser.account.username)
|
||||||
if (humhubUser) {
|
if (humhubUser) {
|
||||||
if (!user.humhubAllowed) {
|
if (!user.humhubAllowed) {
|
||||||
return Promise.resolve(ExecutedHumhubAction.DELETE)
|
return Promise.resolve(ExecutedHumhubAction.DELETE)
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
/* eslint-disable prettier/prettier */
|
/* eslint-disable prettier/prettier */
|
||||||
|
// eslint-disable-next-line import/no-unassigned-import
|
||||||
|
import 'reflect-metadata'
|
||||||
|
import { PublishNameType } from '@/graphql/enum/PublishNameType'
|
||||||
import { communityDbUser } from '@/util/communityUser'
|
import { communityDbUser } from '@/util/communityUser'
|
||||||
|
|
||||||
import { isHumhubUserIdenticalToDbUser } from './compareHumhubUserDbUser'
|
import { isHumhubUserIdenticalToDbUser } from './compareHumhubUserDbUser'
|
||||||
@ -13,6 +16,7 @@ describe('isHumhubUserIdenticalToDbUser', () => {
|
|||||||
defaultUser.alias = 'alias'
|
defaultUser.alias = 'alias'
|
||||||
defaultUser.emailContact.email = 'email@gmail.com'
|
defaultUser.emailContact.email = 'email@gmail.com'
|
||||||
defaultUser.language = 'en'
|
defaultUser.language = 'en'
|
||||||
|
defaultUser.gradidoID = 'gradidoID'
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should return true because humhubUser was created from entity user', () => {
|
it('Should return true because humhubUser was created from entity user', () => {
|
||||||
@ -21,6 +25,20 @@ describe('isHumhubUserIdenticalToDbUser', () => {
|
|||||||
expect(result).toBe(true)
|
expect(result).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Should return false, because last name differ because of publish name type', () => {
|
||||||
|
const humhubUser = new GetUser(defaultUser, 1)
|
||||||
|
defaultUser.humhubPublishName = PublishNameType.PUBLISH_NAME_FIRST
|
||||||
|
const result = isHumhubUserIdenticalToDbUser(humhubUser, defaultUser)
|
||||||
|
expect(result).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should return true, even if alias is empty', () => {
|
||||||
|
defaultUser.alias = ''
|
||||||
|
const humhubUser = new GetUser(defaultUser, 1)
|
||||||
|
const result = isHumhubUserIdenticalToDbUser(humhubUser, defaultUser)
|
||||||
|
expect(result).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
it('Should return false because first name differ', () => {
|
it('Should return false because first name differ', () => {
|
||||||
const humhubUser = new GetUser(defaultUser, 1)
|
const humhubUser = new GetUser(defaultUser, 1)
|
||||||
humhubUser.profile.firstname = 'changed first name'
|
humhubUser.profile.firstname = 'changed first name'
|
||||||
|
|||||||
@ -27,7 +27,8 @@ describe('syncUser function', () => {
|
|||||||
|
|
||||||
it('When humhubUser exists and user.humhubAllowed is false, should return DELETE action', async () => {
|
it('When humhubUser exists and user.humhubAllowed is false, should return DELETE action', async () => {
|
||||||
const humhubUsers = new Map<string, GetUser>()
|
const humhubUsers = new Map<string, GetUser>()
|
||||||
humhubUsers.set(defaultUser.emailContact.email, new GetUser(defaultUser, 1))
|
const humhubUser = new GetUser(defaultUser, 1)
|
||||||
|
humhubUsers.set(humhubUser.account.username, humhubUser)
|
||||||
|
|
||||||
defaultUser.humhubAllowed = false
|
defaultUser.humhubAllowed = false
|
||||||
const result = await syncUser(defaultUser, humhubUsers)
|
const result = await syncUser(defaultUser, humhubUsers)
|
||||||
@ -38,8 +39,8 @@ describe('syncUser function', () => {
|
|||||||
it('When humhubUser exists and user.humhubAllowed is true and there are changes in user data, should return UPDATE action', async () => {
|
it('When humhubUser exists and user.humhubAllowed is true and there are changes in user data, should return UPDATE action', async () => {
|
||||||
const humhubUsers = new Map<string, GetUser>()
|
const humhubUsers = new Map<string, GetUser>()
|
||||||
const humhubUser = new GetUser(defaultUser, 1)
|
const humhubUser = new GetUser(defaultUser, 1)
|
||||||
|
humhubUsers.set(humhubUser.account.username, humhubUser)
|
||||||
humhubUser.account.username = 'test username'
|
humhubUser.account.username = 'test username'
|
||||||
humhubUsers.set(defaultUser.emailContact.email, humhubUser)
|
|
||||||
|
|
||||||
defaultUser.humhubAllowed = true
|
defaultUser.humhubAllowed = true
|
||||||
const result = await syncUser(defaultUser, humhubUsers)
|
const result = await syncUser(defaultUser, humhubUsers)
|
||||||
@ -50,7 +51,7 @@ describe('syncUser function', () => {
|
|||||||
it('When humhubUser exists and user.humhubAllowed is true and there are no changes in user data, should return SKIP action', async () => {
|
it('When humhubUser exists and user.humhubAllowed is true and there are no changes in user data, should return SKIP action', async () => {
|
||||||
const humhubUsers = new Map<string, GetUser>()
|
const humhubUsers = new Map<string, GetUser>()
|
||||||
const humhubUser = new GetUser(defaultUser, 1)
|
const humhubUser = new GetUser(defaultUser, 1)
|
||||||
humhubUsers.set(defaultUser.emailContact.email, humhubUser)
|
humhubUsers.set(humhubUser.account.username, humhubUser)
|
||||||
|
|
||||||
defaultUser.humhubAllowed = true
|
defaultUser.humhubAllowed = true
|
||||||
const result = await syncUser(defaultUser, humhubUsers)
|
const result = await syncUser(defaultUser, humhubUsers)
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { User } from 'database'
|
import { User } from 'database'
|
||||||
|
|
||||||
import { LogError } from '@/server/LogError'
|
import { LogError } from '@/server/LogError'
|
||||||
|
import { backendLogger as logger } from '@/server/logger'
|
||||||
|
|
||||||
import { isHumhubUserIdenticalToDbUser } from './compareHumhubUserDbUser'
|
import { isHumhubUserIdenticalToDbUser } from './compareHumhubUserDbUser'
|
||||||
import { HumHubClient } from './HumHubClient'
|
import { HumHubClient } from './HumHubClient'
|
||||||
@ -12,7 +13,22 @@ export enum ExecutedHumhubAction {
|
|||||||
CREATE,
|
CREATE,
|
||||||
SKIP,
|
SKIP,
|
||||||
DELETE,
|
DELETE,
|
||||||
|
VALIDATION_ERROR,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo: replace with full validation (schema)
|
||||||
|
function isValid(postUser: PostUser, userId: number): boolean {
|
||||||
|
if (postUser.profile.firstname.length > 20) {
|
||||||
|
logger.error('firstname too long for humhub, for user with id:', userId)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (postUser.profile.lastname.length > 20) {
|
||||||
|
logger.error('lastname too long for humhub, for user with id:', userId)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trigger action according to conditions
|
* Trigger action according to conditions
|
||||||
* | User exist on humhub | export to humhub allowed | changes in user data | ACTION
|
* | User exist on humhub | export to humhub allowed | changes in user data | ACTION
|
||||||
@ -21,9 +37,8 @@ export enum ExecutedHumhubAction {
|
|||||||
* | true | true | false | SKIP
|
* | true | true | false | SKIP
|
||||||
* | false | false | ignored | SKIP
|
* | false | false | ignored | SKIP
|
||||||
* | false | true | ignored | CREATE
|
* | false | true | ignored | CREATE
|
||||||
* @param user
|
* @param user user entity
|
||||||
* @param humHubClient
|
* @param humhubUsers user map indices with username
|
||||||
* @param humhubUsers
|
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export async function syncUser(
|
export async function syncUser(
|
||||||
@ -31,7 +46,10 @@ export async function syncUser(
|
|||||||
humhubUsers: Map<string, GetUser>,
|
humhubUsers: Map<string, GetUser>,
|
||||||
): Promise<ExecutedHumhubAction> {
|
): Promise<ExecutedHumhubAction> {
|
||||||
const postUser = new PostUser(user)
|
const postUser = new PostUser(user)
|
||||||
const humhubUser = humhubUsers.get(user.emailContact.email.trim())
|
if (!isValid(postUser, user.id)) {
|
||||||
|
return ExecutedHumhubAction.VALIDATION_ERROR
|
||||||
|
}
|
||||||
|
const humhubUser = humhubUsers.get(postUser.account.username)
|
||||||
const humHubClient = HumHubClient.getInstance()
|
const humHubClient = HumHubClient.getInstance()
|
||||||
if (!humHubClient) {
|
if (!humHubClient) {
|
||||||
throw new LogError('Error creating humhub client')
|
throw new LogError('Error creating humhub client')
|
||||||
|
|||||||
@ -35,12 +35,16 @@ export class PublishNameLogic {
|
|||||||
* @returns user.firstName for PUBLISH_NAME_FIRST, PUBLISH_NAME_FIRST_INITIAL or PUBLISH_NAME_FULL
|
* @returns user.firstName for PUBLISH_NAME_FIRST, PUBLISH_NAME_FIRST_INITIAL or PUBLISH_NAME_FULL
|
||||||
*/
|
*/
|
||||||
public getFirstName(publishNameType: PublishNameType): string {
|
public getFirstName(publishNameType: PublishNameType): string {
|
||||||
|
let firstName = ''
|
||||||
|
if (this.user && typeof this.user.firstName === 'string') {
|
||||||
|
firstName = this.user.firstName
|
||||||
|
}
|
||||||
return [
|
return [
|
||||||
PublishNameType.PUBLISH_NAME_FIRST,
|
PublishNameType.PUBLISH_NAME_FIRST,
|
||||||
PublishNameType.PUBLISH_NAME_FIRST_INITIAL,
|
PublishNameType.PUBLISH_NAME_FIRST_INITIAL,
|
||||||
PublishNameType.PUBLISH_NAME_FULL,
|
PublishNameType.PUBLISH_NAME_FULL,
|
||||||
].includes(publishNameType)
|
].includes(publishNameType)
|
||||||
? this.user.firstName
|
? firstName.slice(0, 20)
|
||||||
: ''
|
: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,10 +55,14 @@ export class PublishNameLogic {
|
|||||||
* first initial from user.lastName for PUBLISH_NAME_FIRST_INITIAL
|
* first initial from user.lastName for PUBLISH_NAME_FIRST_INITIAL
|
||||||
*/
|
*/
|
||||||
public getLastName(publishNameType: PublishNameType): string {
|
public getLastName(publishNameType: PublishNameType): string {
|
||||||
|
let lastName = ''
|
||||||
|
if (this.user && typeof this.user.lastName === 'string') {
|
||||||
|
lastName = this.user.lastName
|
||||||
|
}
|
||||||
return publishNameType === PublishNameType.PUBLISH_NAME_FULL
|
return publishNameType === PublishNameType.PUBLISH_NAME_FULL
|
||||||
? this.user.lastName
|
? lastName.slice(0, 20)
|
||||||
: publishNameType === PublishNameType.PUBLISH_NAME_FIRST_INITIAL
|
: publishNameType === PublishNameType.PUBLISH_NAME_FIRST_INITIAL && lastName.length > 0
|
||||||
? this.user.lastName.charAt(0)
|
? lastName.charAt(0)
|
||||||
: ''
|
: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +93,7 @@ export class PublishNameLogic {
|
|||||||
? this.getUsernameFromAlias()
|
? this.getUsernameFromAlias()
|
||||||
: this.isUsernameFromInitials(publishNameType)
|
: this.isUsernameFromInitials(publishNameType)
|
||||||
? this.getUsernameFromInitials()
|
? this.getUsernameFromInitials()
|
||||||
: (this.getFirstName(publishNameType) + ' ' + this.getLastName(publishNameType)).trim()
|
: `(${this.getFirstName(publishNameType)} ${this.getLastName(publishNameType)}`.trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
public getUsernameFromInitials(): string {
|
public getUsernameFromInitials(): string {
|
||||||
|
|||||||
@ -39,6 +39,7 @@ import { UpdateUserInfosArgs } from '@arg/UpdateUserInfosArgs'
|
|||||||
import { OptInType } from '@enum/OptInType'
|
import { OptInType } from '@enum/OptInType'
|
||||||
import { Order } from '@enum/Order'
|
import { Order } from '@enum/Order'
|
||||||
import { PasswordEncryptionType } from '@enum/PasswordEncryptionType'
|
import { PasswordEncryptionType } from '@enum/PasswordEncryptionType'
|
||||||
|
import { PublishNameType } from '@enum/PublishNameType'
|
||||||
import { UserContactType } from '@enum/UserContactType'
|
import { UserContactType } from '@enum/UserContactType'
|
||||||
import { SearchAdminUsersResult } from '@model/AdminUser'
|
import { SearchAdminUsersResult } from '@model/AdminUser'
|
||||||
// import { Location } from '@model/Location'
|
// import { Location } from '@model/Location'
|
||||||
@ -56,6 +57,7 @@ import { subscribe } from '@/apis/KlicktippController'
|
|||||||
import { encode } from '@/auth/JWT'
|
import { encode } from '@/auth/JWT'
|
||||||
import { RIGHTS } from '@/auth/RIGHTS'
|
import { RIGHTS } from '@/auth/RIGHTS'
|
||||||
import { CONFIG } from '@/config'
|
import { CONFIG } from '@/config'
|
||||||
|
import { PublishNameLogic } from '@/data/PublishName.logic'
|
||||||
import {
|
import {
|
||||||
sendAccountActivationEmail,
|
sendAccountActivationEmail,
|
||||||
sendAccountMultiRegistrationEmail,
|
sendAccountMultiRegistrationEmail,
|
||||||
@ -248,12 +250,12 @@ export class UserResolver {
|
|||||||
try {
|
try {
|
||||||
const result = await humhubUserPromise
|
const result = await humhubUserPromise
|
||||||
user.humhubAllowed = result?.result?.account.status === 1
|
user.humhubAllowed = result?.result?.account.status === 1
|
||||||
if (user.humhubAllowed) {
|
if (user.humhubAllowed && result?.result?.account?.username) {
|
||||||
let spaceId = null
|
let spaceId = null
|
||||||
if (projectBranding) {
|
if (projectBranding) {
|
||||||
spaceId = projectBranding.spaceId
|
spaceId = projectBranding.spaceId
|
||||||
}
|
}
|
||||||
void syncHumhub(null, dbUser, spaceId)
|
await syncHumhub(null, dbUser, result.result.account.username, spaceId)
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error("couldn't reach out to humhub, disable for now", e)
|
logger.error("couldn't reach out to humhub, disable for now", e)
|
||||||
@ -450,7 +452,11 @@ export class UserResolver {
|
|||||||
if (projectBranding) {
|
if (projectBranding) {
|
||||||
spaceId = projectBranding.spaceId
|
spaceId = projectBranding.spaceId
|
||||||
}
|
}
|
||||||
void syncHumhub(null, dbUser, spaceId)
|
try {
|
||||||
|
await syncHumhub(null, dbUser, dbUser.gradidoID, spaceId)
|
||||||
|
} catch (e) {
|
||||||
|
logger.error("createUser: couldn't reach out to humhub, disable for now", e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (redeemCode) {
|
if (redeemCode) {
|
||||||
@ -661,6 +667,10 @@ export class UserResolver {
|
|||||||
)
|
)
|
||||||
const user = getUser(context)
|
const user = getUser(context)
|
||||||
const updateUserInGMS = compareGmsRelevantUserSettings(user, updateUserInfosArgs)
|
const updateUserInGMS = compareGmsRelevantUserSettings(user, updateUserInfosArgs)
|
||||||
|
const publishNameLogic = new PublishNameLogic(user)
|
||||||
|
const oldHumhubUsername = publishNameLogic.getUserIdentifier(
|
||||||
|
user.humhubPublishName as PublishNameType,
|
||||||
|
)
|
||||||
|
|
||||||
// try {
|
// try {
|
||||||
if (firstName) {
|
if (firstName) {
|
||||||
@ -766,7 +776,7 @@ export class UserResolver {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (CONFIG.HUMHUB_ACTIVE) {
|
if (CONFIG.HUMHUB_ACTIVE) {
|
||||||
await syncHumhub(updateUserInfosArgs, user)
|
await syncHumhub(updateUserInfosArgs, user, oldHumhubUsername)
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error('error sync user with humhub', e)
|
logger.error('error sync user with humhub', e)
|
||||||
@ -841,7 +851,7 @@ export class UserResolver {
|
|||||||
}
|
}
|
||||||
const humhubUserAccount = new HumhubAccount(dbUser)
|
const humhubUserAccount = new HumhubAccount(dbUser)
|
||||||
const autoLoginUrlPromise = humhubClient.createAutoLoginUrl(humhubUserAccount.username, project)
|
const autoLoginUrlPromise = humhubClient.createAutoLoginUrl(humhubUserAccount.username, project)
|
||||||
const humhubUser = await syncHumhub(null, dbUser)
|
const humhubUser = await syncHumhub(null, dbUser, humhubUserAccount.username)
|
||||||
if (!humhubUser) {
|
if (!humhubUser) {
|
||||||
throw new LogError("user don't exist (any longer) on humhub and couldn't be created")
|
throw new LogError("user don't exist (any longer) on humhub and couldn't be created")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,7 +31,7 @@ describe('syncHumhub', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('Should not sync if no relevant changes', async () => {
|
it('Should not sync if no relevant changes', async () => {
|
||||||
await syncHumhub(mockUpdateUserInfosArg, new User())
|
await syncHumhub(mockUpdateUserInfosArg, new User(), 'username')
|
||||||
expect(HumHubClient.getInstance).not.toBeCalled()
|
expect(HumHubClient.getInstance).not.toBeCalled()
|
||||||
// language logging from some other place
|
// language logging from some other place
|
||||||
expect(logger.debug).toBeCalledTimes(5)
|
expect(logger.debug).toBeCalledTimes(5)
|
||||||
@ -41,7 +41,7 @@ describe('syncHumhub', () => {
|
|||||||
it('Should retrieve user from humhub and sync if relevant changes', async () => {
|
it('Should retrieve user from humhub and sync if relevant changes', async () => {
|
||||||
mockUpdateUserInfosArg.firstName = 'New' // Relevant changes
|
mockUpdateUserInfosArg.firstName = 'New' // Relevant changes
|
||||||
mockUser.firstName = 'New'
|
mockUser.firstName = 'New'
|
||||||
await syncHumhub(mockUpdateUserInfosArg, mockUser)
|
await syncHumhub(mockUpdateUserInfosArg, mockUser, 'username')
|
||||||
expect(logger.debug).toHaveBeenCalledTimes(8) // Four language logging calls, two debug calls in function, one for not syncing
|
expect(logger.debug).toHaveBeenCalledTimes(8) // Four language logging calls, two debug calls in function, one for not syncing
|
||||||
expect(logger.info).toHaveBeenLastCalledWith('finished sync user with humhub', {
|
expect(logger.info).toHaveBeenLastCalledWith('finished sync user with humhub', {
|
||||||
localId: mockUser.id,
|
localId: mockUser.id,
|
||||||
|
|||||||
@ -2,10 +2,9 @@ import { User } from 'database'
|
|||||||
|
|
||||||
import { HumHubClient } from '@/apis/humhub/HumHubClient'
|
import { HumHubClient } from '@/apis/humhub/HumHubClient'
|
||||||
import { GetUser } from '@/apis/humhub/model/GetUser'
|
import { GetUser } from '@/apis/humhub/model/GetUser'
|
||||||
|
import { PostUser } from '@/apis/humhub/model/PostUser'
|
||||||
import { ExecutedHumhubAction, syncUser } from '@/apis/humhub/syncUser'
|
import { ExecutedHumhubAction, syncUser } from '@/apis/humhub/syncUser'
|
||||||
import { PublishNameLogic } from '@/data/PublishName.logic'
|
|
||||||
import { UpdateUserInfosArgs } from '@/graphql/arg/UpdateUserInfosArgs'
|
import { UpdateUserInfosArgs } from '@/graphql/arg/UpdateUserInfosArgs'
|
||||||
import { PublishNameType } from '@/graphql/enum/PublishNameType'
|
|
||||||
import { backendLogger as logger } from '@/server/logger'
|
import { backendLogger as logger } from '@/server/logger'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -17,6 +16,7 @@ import { backendLogger as logger } from '@/server/logger'
|
|||||||
export async function syncHumhub(
|
export async function syncHumhub(
|
||||||
updateUserInfosArg: UpdateUserInfosArgs | null,
|
updateUserInfosArg: UpdateUserInfosArgs | null,
|
||||||
user: User,
|
user: User,
|
||||||
|
oldHumhubUsername: string,
|
||||||
spaceId?: number | null,
|
spaceId?: number | null,
|
||||||
): Promise<GetUser | null | undefined> {
|
): Promise<GetUser | null | undefined> {
|
||||||
// check for humhub relevant changes
|
// check for humhub relevant changes
|
||||||
@ -38,15 +38,13 @@ export async function syncHumhub(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
logger.debug('retrieve user from humhub')
|
logger.debug('retrieve user from humhub')
|
||||||
const userNameLogic = new PublishNameLogic(user)
|
let humhubUser = await humhubClient.userByUsername(oldHumhubUsername)
|
||||||
const username = userNameLogic.getUserIdentifier(user.humhubPublishName as PublishNameType)
|
|
||||||
let humhubUser = await humhubClient.userByUsername(username)
|
|
||||||
if (!humhubUser) {
|
if (!humhubUser) {
|
||||||
humhubUser = await humhubClient.userByEmail(user.emailContact.email)
|
humhubUser = await humhubClient.userByEmail(user.emailContact.email)
|
||||||
}
|
}
|
||||||
const humhubUsers = new Map<string, GetUser>()
|
const humhubUsers = new Map<string, GetUser>()
|
||||||
if (humhubUser) {
|
if (humhubUser) {
|
||||||
humhubUsers.set(user.emailContact.email, humhubUser)
|
humhubUsers.set(humhubUser.account.username, humhubUser)
|
||||||
}
|
}
|
||||||
logger.debug('update user at humhub')
|
logger.debug('update user at humhub')
|
||||||
const result = await syncUser(user, humhubUsers)
|
const result = await syncUser(user, humhubUsers)
|
||||||
@ -63,7 +61,8 @@ export async function syncHumhub(
|
|||||||
logger.debug(`user added to space ${spaceId}`)
|
logger.debug(`user added to space ${spaceId}`)
|
||||||
}
|
}
|
||||||
if (result !== ExecutedHumhubAction.SKIP) {
|
if (result !== ExecutedHumhubAction.SKIP) {
|
||||||
return await humhubClient.userByUsername(username)
|
const getUser = new PostUser(user)
|
||||||
|
return await humhubClient.userByUsername(getUser.account.username)
|
||||||
}
|
}
|
||||||
return humhubUser
|
return humhubUser
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,8 @@ import { backendLogger as logger } from '@/server/logger'
|
|||||||
|
|
||||||
CONFIG.EMAIL = true
|
CONFIG.EMAIL = true
|
||||||
CONFIG.EMAIL_TEST_MODUS = false
|
CONFIG.EMAIL_TEST_MODUS = false
|
||||||
|
CONFIG.HUMHUB_ACTIVE = false
|
||||||
|
CONFIG.GMS_ACTIVE = false
|
||||||
|
|
||||||
jest.setTimeout(1000000)
|
jest.setTimeout(1000000)
|
||||||
|
|
||||||
|
|||||||
@ -67,6 +67,7 @@ const props = defineProps({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits([
|
const emit = defineEmits([
|
||||||
|
'close-all-open-collapse',
|
||||||
'update-list-contributions',
|
'update-list-contributions',
|
||||||
'update-contribution-form',
|
'update-contribution-form',
|
||||||
'delete-contribution',
|
'delete-contribution',
|
||||||
|
|||||||
@ -14,6 +14,7 @@ vi.mock('@vue/apollo-composable', () => ({
|
|||||||
onResult: vi.fn(),
|
onResult: vi.fn(),
|
||||||
onError: vi.fn(),
|
onError: vi.fn(),
|
||||||
load: vi.fn(),
|
load: vi.fn(),
|
||||||
|
refetch: vi.fn(),
|
||||||
})),
|
})),
|
||||||
useMutation: vi.fn(() => ({
|
useMutation: vi.fn(() => ({
|
||||||
mutate: vi.fn(),
|
mutate: vi.fn(),
|
||||||
|
|||||||
@ -246,7 +246,7 @@ function deleteContribution(item) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const { onResult, onError, load } = useLazyQuery(listContributionMessages, {
|
const { onResult, onError, load, refetch } = useLazyQuery(listContributionMessages, {
|
||||||
contributionId: props.contributionId,
|
contributionId: props.contributionId,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -254,9 +254,15 @@ function getListContributionMessages(closeCollapse = true) {
|
|||||||
if (closeCollapse) {
|
if (closeCollapse) {
|
||||||
emit('close-all-open-collapse')
|
emit('close-all-open-collapse')
|
||||||
}
|
}
|
||||||
load(listContributionMessages, {
|
const variables = {
|
||||||
contributionId: props.contributionId,
|
contributionId: props.contributionId,
|
||||||
})
|
}
|
||||||
|
// load works only once and return false on second call
|
||||||
|
if (!load(listContributionMessages, variables)) {
|
||||||
|
// update list data every time getListContributionMessages is called
|
||||||
|
// because it could be added new messages
|
||||||
|
refetch(variables)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onResult((resultValue) => {
|
onResult((resultValue) => {
|
||||||
|
|||||||
@ -95,6 +95,9 @@ describe('GddTransactionList', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('timestamp property', () => {
|
describe('timestamp property', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await wrapper.setProps({ timestamp: new Date().getTime() })
|
||||||
|
})
|
||||||
it('emits update-transactions when timestamp changes', async () => {
|
it('emits update-transactions when timestamp changes', async () => {
|
||||||
await wrapper.setProps({ timestamp: 0 })
|
await wrapper.setProps({ timestamp: 0 })
|
||||||
expect(wrapper.emitted('update-transactions')).toBeTruthy()
|
expect(wrapper.emitted('update-transactions')).toBeTruthy()
|
||||||
|
|||||||
@ -101,7 +101,7 @@ export default {
|
|||||||
this.updateTransactions()
|
this.updateTransactions()
|
||||||
},
|
},
|
||||||
timestamp: {
|
timestamp: {
|
||||||
immediate: true,
|
immediate: false,
|
||||||
handler: 'updateTransactions',
|
handler: 'updateTransactions',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -256,8 +256,8 @@ export const communityStatistics = gql`
|
|||||||
`
|
`
|
||||||
|
|
||||||
export const searchAdminUsers = gql`
|
export const searchAdminUsers = gql`
|
||||||
query {
|
query ($pageSize: Int = 25, $currentPage: Int = 1, $order: Order = ASC) {
|
||||||
searchAdminUsers {
|
searchAdminUsers(pageSize: $pageSize, currentPage: $currentPage, order: $order) {
|
||||||
userCount
|
userCount
|
||||||
userList {
|
userList {
|
||||||
firstName
|
firstName
|
||||||
|
|||||||
56
frontend/src/graphql/transactions.graphql
Normal file
56
frontend/src/graphql/transactions.graphql
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
fragment balanceFields on Balance {
|
||||||
|
balance
|
||||||
|
balanceGDT
|
||||||
|
count
|
||||||
|
linkCount
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment transactionFields on Transaction {
|
||||||
|
id
|
||||||
|
typeId
|
||||||
|
amount
|
||||||
|
balance
|
||||||
|
previousBalance
|
||||||
|
balanceDate
|
||||||
|
memo
|
||||||
|
linkedUser {
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
communityUuid
|
||||||
|
communityName
|
||||||
|
gradidoID
|
||||||
|
alias
|
||||||
|
}
|
||||||
|
decay {
|
||||||
|
decay
|
||||||
|
start
|
||||||
|
end
|
||||||
|
duration
|
||||||
|
}
|
||||||
|
linkId
|
||||||
|
}
|
||||||
|
|
||||||
|
query transactionsQuery($currentPage: Int = 1, $pageSize: Int = 25, $order: Order = DESC) {
|
||||||
|
transactionList(currentPage: $currentPage, pageSize: $pageSize, order: $order) {
|
||||||
|
balance {
|
||||||
|
...balanceFields
|
||||||
|
}
|
||||||
|
transactions {
|
||||||
|
...transactionFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query transactionsUserCountQuery($currentPage: Int = 1, $pageSize: Int = 25, $order: Order = DESC) {
|
||||||
|
transactionList(currentPage: $currentPage, pageSize: $pageSize, order: $order) {
|
||||||
|
balance {
|
||||||
|
...balanceFields
|
||||||
|
}
|
||||||
|
transactions {
|
||||||
|
...transactionFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
communityStatistics {
|
||||||
|
totalUsers
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,6 +5,7 @@ import DashboardLayout from './DashboardLayout'
|
|||||||
import { createStore } from 'vuex'
|
import { createStore } from 'vuex'
|
||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
import routes from '@/routes/routes'
|
import routes from '@/routes/routes'
|
||||||
|
import { useQuery } from '@vue/apollo-composable'
|
||||||
|
|
||||||
const toastErrorSpy = vi.fn()
|
const toastErrorSpy = vi.fn()
|
||||||
|
|
||||||
@ -14,18 +15,35 @@ vi.mock('@/composables/useToast', () => ({
|
|||||||
}),
|
}),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const mockQueryFn = vi.fn()
|
|
||||||
const mockRefetchFn = vi.fn()
|
const mockRefetchFn = vi.fn()
|
||||||
const mockMutateFn = vi.fn()
|
const mockMutateFn = vi.fn()
|
||||||
|
let onErrorHandler
|
||||||
|
let onResultHandler
|
||||||
const mockQueryResult = ref(null)
|
const mockQueryResult = ref(null)
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
vi.mock('@vue/apollo-composable', () => ({
|
vi.mock('@vue/apollo-composable', () => ({
|
||||||
useLazyQuery: vi.fn(() => ({
|
useQuery: vi.fn(() => ({
|
||||||
load: mockQueryFn,
|
|
||||||
refetch: mockRefetchFn,
|
refetch: mockRefetchFn,
|
||||||
result: mockQueryResult,
|
result: mockQueryResult,
|
||||||
onResult: vi.fn(),
|
onResult: (handler) => {
|
||||||
onError: vi.fn(),
|
onResultHandler = handler
|
||||||
|
},
|
||||||
|
onError: (handler) => {
|
||||||
|
onErrorHandler = handler
|
||||||
|
},
|
||||||
|
loading,
|
||||||
|
})),
|
||||||
|
useLazyQuery: vi.fn(() => ({
|
||||||
|
refetch: mockRefetchFn,
|
||||||
|
result: mockQueryResult,
|
||||||
|
onResult: (handler) => {
|
||||||
|
onResultHandler = handler
|
||||||
|
},
|
||||||
|
onError: (handler) => {
|
||||||
|
onErrorHandler = handler
|
||||||
|
},
|
||||||
|
loading,
|
||||||
})),
|
})),
|
||||||
useMutation: vi.fn(() => ({
|
useMutation: vi.fn(() => ({
|
||||||
mutate: mockMutateFn,
|
mutate: mockMutateFn,
|
||||||
@ -103,17 +121,6 @@ describe('DashboardLayout', () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.useFakeTimers()
|
vi.useFakeTimers()
|
||||||
mockQueryFn.mockResolvedValue({
|
|
||||||
communityStatistics: {
|
|
||||||
totalUsers: 3113,
|
|
||||||
activeUsers: 1057,
|
|
||||||
deletedUsers: 35,
|
|
||||||
totalGradidoCreated: '4083774.05000000000000000000',
|
|
||||||
totalGradidoDecayed: '-1062639.13634129622923372197',
|
|
||||||
totalGradidoAvailable: '2513565.869444365732411569',
|
|
||||||
totalGradidoUnbookedDecayed: '-500474.6738366222166261272',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
wrapper = createWrapper()
|
wrapper = createWrapper()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -135,31 +142,32 @@ describe('DashboardLayout', () => {
|
|||||||
describe('after a timeout', () => {
|
describe('after a timeout', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
vi.advanceTimersByTime(1500)
|
vi.advanceTimersByTime(1500)
|
||||||
|
loading.value = false
|
||||||
await nextTick()
|
await nextTick()
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('update transactions', () => {
|
describe('update transactions', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
mockQueryResult.value = {
|
onResultHandler({
|
||||||
transactionList: {
|
data: {
|
||||||
balance: {
|
transactionList: {
|
||||||
balanceGDT: '100',
|
balance: {
|
||||||
count: 4,
|
balanceGDT: '100',
|
||||||
linkCount: 8,
|
count: 4,
|
||||||
balance: '1450',
|
linkCount: 8,
|
||||||
|
balance: '1450',
|
||||||
|
},
|
||||||
|
transactions: ['transaction1', 'transaction2', 'transaction3', 'transaction4'],
|
||||||
},
|
},
|
||||||
transactions: ['transaction1', 'transaction2', 'transaction3', 'transaction4'],
|
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
|
|
||||||
mockQueryFn.mockResolvedValue(mockQueryResult.value)
|
|
||||||
|
|
||||||
await wrapper.vm.updateTransactions({ currentPage: 2, pageSize: 5 })
|
await wrapper.vm.updateTransactions({ currentPage: 2, pageSize: 5 })
|
||||||
await nextTick() // Ensure all promises are resolved
|
await nextTick() // Ensure all promises are resolved
|
||||||
})
|
})
|
||||||
|
|
||||||
it('load call to the API', () => {
|
it('load call to the API', () => {
|
||||||
expect(mockQueryFn).toHaveBeenCalled()
|
expect(useQuery).toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('updates balance', () => {
|
it('updates balance', () => {
|
||||||
@ -190,7 +198,7 @@ describe('DashboardLayout', () => {
|
|||||||
|
|
||||||
describe('update transactions returns error', () => {
|
describe('update transactions returns error', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
mockQueryFn.mockRejectedValue(new Error('Ouch!'))
|
wrapper.vm.skeleton = false
|
||||||
await wrapper
|
await wrapper
|
||||||
.findComponent({ ref: 'router-view' })
|
.findComponent({ ref: 'router-view' })
|
||||||
.vm.$emit('update-transactions', { currentPage: 2, pageSize: 5 })
|
.vm.$emit('update-transactions', { currentPage: 2, pageSize: 5 })
|
||||||
@ -202,6 +210,7 @@ describe('DashboardLayout', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('toasts the error message', () => {
|
it('toasts the error message', () => {
|
||||||
|
onErrorHandler({ message: 'Ouch!' })
|
||||||
expect(toastErrorSpy).toHaveBeenCalledWith('Ouch!')
|
expect(toastErrorSpy).toHaveBeenCalledWith('Ouch!')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -187,11 +187,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue'
|
import { onMounted, ref } from 'vue'
|
||||||
import { useStore } from 'vuex'
|
import { useStore } from 'vuex'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { useLazyQuery, useMutation } from '@vue/apollo-composable'
|
import { useQuery, useMutation } from '@vue/apollo-composable'
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
import ContentHeader from '@/layouts/templates/ContentHeader'
|
import ContentHeader from '@/layouts/templates/ContentHeader'
|
||||||
import CommunityTemplate from '@/layouts/templates/CommunityTemplate'
|
import CommunityTemplate from '@/layouts/templates/CommunityTemplate'
|
||||||
import Breadcrumb from '@/components/Breadcrumb/breadcrumb'
|
import Breadcrumb from '@/components/Breadcrumb/breadcrumb'
|
||||||
@ -207,21 +206,23 @@ import GdtAmount from '@/components/Template/ContentHeader/GdtAmount'
|
|||||||
import CommunityMember from '@/components/Template/ContentHeader/CommunityMember'
|
import CommunityMember from '@/components/Template/ContentHeader/CommunityMember'
|
||||||
import NavCommunity from '@/components/Template/ContentHeader/NavCommunity'
|
import NavCommunity from '@/components/Template/ContentHeader/NavCommunity'
|
||||||
import LastTransactions from '@/components/Template/RightSide/LastTransactions'
|
import LastTransactions from '@/components/Template/RightSide/LastTransactions'
|
||||||
import { transactionsQuery, communityStatistics } from '@/graphql/queries'
|
import { transactionsUserCountQuery } from '@/graphql/transactions.graphql'
|
||||||
import { logout } from '@/graphql/mutations'
|
import { logout } from '@/graphql/mutations'
|
||||||
import CONFIG from '@/config'
|
import CONFIG from '@/config'
|
||||||
import { useAppToast } from '@/composables/useToast'
|
import { useAppToast } from '@/composables/useToast'
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { load: useCommunityStatsQuery } = useLazyQuery(communityStatistics)
|
|
||||||
const {
|
const {
|
||||||
load: useTransactionsQuery,
|
|
||||||
refetch: useRefetchTransactionsQuery,
|
refetch: useRefetchTransactionsQuery,
|
||||||
result: transactionQueryResult,
|
onError,
|
||||||
} = useLazyQuery(transactionsQuery, {}, { fetchPolicy: 'network-only' })
|
onResult,
|
||||||
|
} = useQuery(
|
||||||
|
transactionsUserCountQuery,
|
||||||
|
{ currentPage: 1, pageSize: 10, order: 'DESC' },
|
||||||
|
{ fetchPolicy: 'network-only' },
|
||||||
|
)
|
||||||
const { mutate: useLogoutMutation } = useMutation(logout)
|
const { mutate: useLogoutMutation } = useMutation(logout)
|
||||||
const { t } = useI18n()
|
|
||||||
const { toastError } = useAppToast()
|
const { toastError } = useAppToast()
|
||||||
|
|
||||||
const balance = ref(0)
|
const balance = ref(0)
|
||||||
@ -230,15 +231,11 @@ const transactions = ref([])
|
|||||||
const transactionCount = ref(0)
|
const transactionCount = ref(0)
|
||||||
const transactionLinkCount = ref(0)
|
const transactionLinkCount = ref(0)
|
||||||
const pending = ref(true)
|
const pending = ref(true)
|
||||||
const visible = ref(false)
|
|
||||||
const hamburger = ref(true)
|
|
||||||
const darkMode = ref(false)
|
|
||||||
const skeleton = ref(true)
|
const skeleton = ref(true)
|
||||||
const totalUsers = ref(null)
|
const totalUsers = ref(null)
|
||||||
|
|
||||||
|
// only error correction, normally skeleton should be visible less than 1500ms
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
updateTransactions({ currentPage: 1, pageSize: 10 })
|
|
||||||
getCommunityStatistics()
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
skeleton.value = false
|
skeleton.value = false
|
||||||
}, 1500)
|
}, 1500)
|
||||||
@ -255,50 +252,38 @@ const logoutUser = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateTransactions = async ({ currentPage, pageSize }) => {
|
const updateTransactions = ({ currentPage, pageSize }) => {
|
||||||
pending.value = true
|
pending.value = true
|
||||||
try {
|
useRefetchTransactionsQuery({ currentPage, pageSize })
|
||||||
await loadOrFetchTransactionQuery({ currentPage, pageSize })
|
|
||||||
if (!transactionQueryResult) return
|
|
||||||
const { transactionList } = transactionQueryResult.value
|
|
||||||
GdtBalance.value =
|
|
||||||
transactionList.balance.balanceGDT === null ? 0 : Number(transactionList.balance.balanceGDT)
|
|
||||||
transactions.value = transactionList.transactions
|
|
||||||
balance.value = Number(transactionList.balance.balance)
|
|
||||||
transactionCount.value = transactionList.balance.count
|
|
||||||
transactionLinkCount.value = transactionList.balance.linkCount
|
|
||||||
pending.value = false
|
|
||||||
} catch (error) {
|
|
||||||
pending.value = true
|
|
||||||
transactionCount.value = -1
|
|
||||||
toastError(error.message)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadOrFetchTransactionQuery = async (queryVariables = { currentPage: 1, pageSize: 25 }) => {
|
onResult((value) => {
|
||||||
return (
|
if (value && value.data) {
|
||||||
(await useTransactionsQuery(transactionsQuery, queryVariables)) ||
|
if (value.data.transactionList) {
|
||||||
(await useRefetchTransactionsQuery(queryVariables))
|
const tr = value.data.transactionList
|
||||||
)
|
GdtBalance.value = tr.balance?.balanceGDT === null ? 0 : Number(tr.balance?.balanceGDT)
|
||||||
}
|
transactions.value = tr.transactions || []
|
||||||
|
balance.value = Number(tr.balance?.balance) || 0
|
||||||
const getCommunityStatistics = async () => {
|
transactionCount.value = tr.balance?.count || 0
|
||||||
try {
|
transactionLinkCount.value = tr.balance?.linkCount || 0
|
||||||
const result = await useCommunityStatsQuery()
|
}
|
||||||
totalUsers.value = result.communityStatistics.totalUsers
|
if (value.data.communityStatistics) {
|
||||||
} catch {
|
totalUsers.value = value.data.communityStatistics.totalUsers || 0
|
||||||
toastError(t('communityStatistics has no result, use default data'))
|
}
|
||||||
}
|
}
|
||||||
}
|
pending.value = false
|
||||||
|
skeleton.value = false
|
||||||
|
})
|
||||||
|
|
||||||
|
onError((error) => {
|
||||||
|
transactionCount.value = -1
|
||||||
|
toastError(error.message)
|
||||||
|
})
|
||||||
|
|
||||||
const admin = () => {
|
const admin = () => {
|
||||||
window.location.assign(CONFIG.ADMIN_AUTH_URL + store.state.token)
|
window.location.assign(CONFIG.ADMIN_AUTH_URL + store.state.token)
|
||||||
store.dispatch('logout') // logout without redirect
|
store.dispatch('logout') // logout without redirect
|
||||||
}
|
}
|
||||||
|
|
||||||
const setVisible = (bool) => {
|
|
||||||
visible.value = bool
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
.breadcrumb {
|
.breadcrumb {
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
:show-pagination="true"
|
:show-pagination="true"
|
||||||
:page-size="pageSize"
|
:page-size="pageSize"
|
||||||
@close-all-open-collapse="closeAllOpenCollapse"
|
@close-all-open-collapse="closeAllOpenCollapse"
|
||||||
@update-list-contributions="handleUpdateListAllContributions"
|
@update-list-contributions="handleUpdateListContributions"
|
||||||
@update-contribution-form="handleUpdateContributionForm"
|
@update-contribution-form="handleUpdateContributionForm"
|
||||||
@delete-contribution="handleDeleteContribution"
|
@delete-contribution="handleDeleteContribution"
|
||||||
@update-status="updateStatus"
|
@update-status="updateStatus"
|
||||||
@ -272,10 +272,6 @@ const handleUpdateContributionForm = (item) => {
|
|||||||
router.push({ params: { tab: 'contribute' } })
|
router.push({ params: { tab: 'contribute' } })
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateTransactions = (pagination) => {
|
|
||||||
emit('update-transactions', pagination)
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateStatus = (id) => {
|
const updateStatus = (id) => {
|
||||||
const item = items.value.find((item) => item.id === id)
|
const item = items.value.find((item) => item.id === id)
|
||||||
if (item) {
|
if (item) {
|
||||||
|
|||||||
@ -49,7 +49,11 @@ const moderators = computed(() => itemsAdminUser.value.filter((item) => item.rol
|
|||||||
|
|
||||||
const { onResult: onContributionLinksResult, onError: onContributionLinksError } =
|
const { onResult: onContributionLinksResult, onError: onContributionLinksError } =
|
||||||
useQuery(listContributionLinks)
|
useQuery(listContributionLinks)
|
||||||
const { onResult: onAdminUsersResult, onError: onAdminUsersError } = useQuery(searchAdminUsers)
|
const { onResult: onAdminUsersResult, onError: onAdminUsersError } = useQuery(searchAdminUsers, {
|
||||||
|
pageSize: 25,
|
||||||
|
currentPage: 1,
|
||||||
|
order: 'ASC',
|
||||||
|
})
|
||||||
|
|
||||||
onContributionLinksResult(({ data }) => {
|
onContributionLinksResult(({ data }) => {
|
||||||
if (data) {
|
if (data) {
|
||||||
@ -72,12 +76,4 @@ onContributionLinksError(() => {
|
|||||||
onAdminUsersError(() => {
|
onAdminUsersError(() => {
|
||||||
toastError('searchAdminUsers has no result, use default data')
|
toastError('searchAdminUsers has no result, use default data')
|
||||||
})
|
})
|
||||||
|
|
||||||
const updateTransactions = (pagination) => {
|
|
||||||
emit('update-transactions', pagination)
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
updateTransactions(0)
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -172,7 +172,4 @@ function onBack() {
|
|||||||
function updateTransactions(pagination) {
|
function updateTransactions(pagination) {
|
||||||
emit('update-transactions', pagination)
|
emit('update-transactions', pagination)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equivalent to created hook
|
|
||||||
updateTransactions({})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user