mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge remote-tracking branch 'origin/master' into 2428-feature-federation-implement-multiple-apollo-graphql-endpoints
This commit is contained in:
commit
4c4979f8eb
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@ -527,7 +527,7 @@ jobs:
|
|||||||
report_name: Coverage Backend
|
report_name: Coverage Backend
|
||||||
type: lcov
|
type: lcov
|
||||||
result_path: ./backend/coverage/lcov.info
|
result_path: ./backend/coverage/lcov.info
|
||||||
min_coverage: 76
|
min_coverage: 78
|
||||||
token: ${{ github.token }}
|
token: ${{ github.token }}
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|||||||
@ -4141,9 +4141,9 @@ caniuse-api@^3.0.0:
|
|||||||
lodash.uniq "^4.5.0"
|
lodash.uniq "^4.5.0"
|
||||||
|
|
||||||
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001271:
|
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001271:
|
||||||
version "1.0.30001354"
|
version "1.0.30001442"
|
||||||
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001354.tgz"
|
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001442.tgz"
|
||||||
integrity sha512-mImKeCkyGDAHNywYFA4bqnLAzTUvVkqPvhY4DV47X+Gl2c5Z8c3KNETnXp14GQt11LvxE8AwjzGxJ+rsikiOzg==
|
integrity sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow==
|
||||||
|
|
||||||
capture-exit@^2.0.0:
|
capture-exit@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
|
|||||||
@ -10,7 +10,7 @@ Decimal.set({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const constants = {
|
const constants = {
|
||||||
DB_VERSION: '0058-add_communities_table',
|
DB_VERSION: '0059-add_hide_amount_to_users',
|
||||||
DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0
|
DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0
|
||||||
LOG4JS_CONFIG: 'log4js-config.json',
|
LOG4JS_CONFIG: 'log4js-config.json',
|
||||||
// default log level on production should be info
|
// default log level on production should be info
|
||||||
@ -70,11 +70,13 @@ const email = {
|
|||||||
EMAIL: process.env.EMAIL === 'true' || false,
|
EMAIL: process.env.EMAIL === 'true' || false,
|
||||||
EMAIL_TEST_MODUS: process.env.EMAIL_TEST_MODUS === 'true' || false,
|
EMAIL_TEST_MODUS: process.env.EMAIL_TEST_MODUS === 'true' || false,
|
||||||
EMAIL_TEST_RECEIVER: process.env.EMAIL_TEST_RECEIVER || 'stage1@gradido.net',
|
EMAIL_TEST_RECEIVER: process.env.EMAIL_TEST_RECEIVER || 'stage1@gradido.net',
|
||||||
EMAIL_USERNAME: process.env.EMAIL_USERNAME || 'gradido_email',
|
EMAIL_USERNAME: process.env.EMAIL_USERNAME || '',
|
||||||
EMAIL_SENDER: process.env.EMAIL_SENDER || 'info@gradido.net',
|
EMAIL_SENDER: process.env.EMAIL_SENDER || 'info@gradido.net',
|
||||||
EMAIL_PASSWORD: process.env.EMAIL_PASSWORD || 'xxx',
|
EMAIL_PASSWORD: process.env.EMAIL_PASSWORD || '',
|
||||||
EMAIL_SMTP_URL: process.env.EMAIL_SMTP_URL || 'gmail.com',
|
EMAIL_SMTP_URL: process.env.EMAIL_SMTP_URL || 'mailserver',
|
||||||
EMAIL_SMTP_PORT: process.env.EMAIL_SMTP_PORT || '587',
|
EMAIL_SMTP_PORT: process.env.EMAIL_SMTP_PORT || '1025',
|
||||||
|
// eslint-disable-next-line no-unneeded-ternary
|
||||||
|
EMAIL_TLS: process.env.EMAIL_TLS === 'false' ? false : true,
|
||||||
EMAIL_LINK_VERIFICATION:
|
EMAIL_LINK_VERIFICATION:
|
||||||
process.env.EMAIL_LINK_VERIFICATION || 'http://localhost/checkEmail/{optin}{code}',
|
process.env.EMAIL_LINK_VERIFICATION || 'http://localhost/checkEmail/{optin}{code}',
|
||||||
EMAIL_LINK_SETPASSWORD:
|
EMAIL_LINK_SETPASSWORD:
|
||||||
|
|||||||
@ -41,7 +41,7 @@ export const sendEmailTranslated = async (params: {
|
|||||||
host: CONFIG.EMAIL_SMTP_URL,
|
host: CONFIG.EMAIL_SMTP_URL,
|
||||||
port: Number(CONFIG.EMAIL_SMTP_PORT),
|
port: Number(CONFIG.EMAIL_SMTP_PORT),
|
||||||
secure: false, // true for 465, false for other ports
|
secure: false, // true for 465, false for other ports
|
||||||
requireTLS: true,
|
requireTLS: CONFIG.EMAIL_TLS,
|
||||||
auth: {
|
auth: {
|
||||||
user: CONFIG.EMAIL_USERNAME,
|
user: CONFIG.EMAIL_USERNAME,
|
||||||
pass: CONFIG.EMAIL_PASSWORD,
|
pass: CONFIG.EMAIL_PASSWORD,
|
||||||
|
|||||||
@ -19,4 +19,10 @@ export default class UpdateUserInfosArgs {
|
|||||||
|
|
||||||
@Field({ nullable: true })
|
@Field({ nullable: true })
|
||||||
passwordNew?: string
|
passwordNew?: string
|
||||||
|
|
||||||
|
@Field({ nullable: true })
|
||||||
|
hideAmountGDD?: boolean
|
||||||
|
|
||||||
|
@Field({ nullable: true })
|
||||||
|
hideAmountGDT?: boolean
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,6 +27,8 @@ export class User {
|
|||||||
this.klickTipp = null
|
this.klickTipp = null
|
||||||
this.hasElopage = null
|
this.hasElopage = null
|
||||||
this.creation = creation
|
this.creation = creation
|
||||||
|
this.hideAmountGDD = user.hideAmountGDD
|
||||||
|
this.hideAmountGDT = user.hideAmountGDT
|
||||||
}
|
}
|
||||||
|
|
||||||
@Field(() => Number)
|
@Field(() => Number)
|
||||||
@ -72,6 +74,12 @@ export class User {
|
|||||||
@Field(() => String)
|
@Field(() => String)
|
||||||
language: string
|
language: string
|
||||||
|
|
||||||
|
@Field(() => Boolean)
|
||||||
|
hideAmountGDD: boolean
|
||||||
|
|
||||||
|
@Field(() => Boolean)
|
||||||
|
hideAmountGDT: boolean
|
||||||
|
|
||||||
// This is not the users publisherId, but the one of the users who recommend him
|
// This is not the users publisherId, but the one of the users who recommend him
|
||||||
@Field(() => Number, { nullable: true })
|
@Field(() => Number, { nullable: true })
|
||||||
publisherId: number | null
|
publisherId: number | null
|
||||||
|
|||||||
@ -32,7 +32,7 @@ export class BalanceResolver {
|
|||||||
|
|
||||||
const lastTransaction = context.lastTransaction
|
const lastTransaction = context.lastTransaction
|
||||||
? context.lastTransaction
|
? context.lastTransaction
|
||||||
: await dbTransaction.findOne({ userId: user.id }, { order: { balanceDate: 'DESC' } })
|
: await dbTransaction.findOne({ userId: user.id }, { order: { id: 'DESC' } })
|
||||||
|
|
||||||
logger.debug(`lastTransaction=${lastTransaction}`)
|
logger.debug(`lastTransaction=${lastTransaction}`)
|
||||||
|
|
||||||
|
|||||||
@ -1146,13 +1146,21 @@ describe('ContributionResolver', () => {
|
|||||||
const now = new Date()
|
const now = new Date()
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
creation = await creationFactory(testEnv, {
|
await mutate({
|
||||||
|
mutation: adminCreateContribution,
|
||||||
|
variables: {
|
||||||
email: 'peter@lustig.de',
|
email: 'peter@lustig.de',
|
||||||
amount: 400,
|
amount: 400,
|
||||||
memo: 'Herzlich Willkommen bei Gradido!',
|
memo: 'Herzlich Willkommen bei Gradido!',
|
||||||
creationDate: contributionDateFormatter(
|
creationDate: contributionDateFormatter(
|
||||||
new Date(now.getFullYear(), now.getMonth() - 1, 1),
|
new Date(now.getFullYear(), now.getMonth() - 1, 1),
|
||||||
),
|
),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
creation = await Contribution.findOneOrFail({
|
||||||
|
where: {
|
||||||
|
memo: 'Herzlich Willkommen bei Gradido!',
|
||||||
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -1879,6 +1887,10 @@ describe('ContributionResolver', () => {
|
|||||||
new Date(now.getFullYear(), now.getMonth() - 2, 1),
|
new Date(now.getFullYear(), now.getMonth() - 2, 1),
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
|
await query({
|
||||||
|
query: login,
|
||||||
|
variables: { email: 'peter@lustig.de', password: 'Aa12345_' },
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns true', async () => {
|
it('returns true', async () => {
|
||||||
@ -1935,6 +1947,23 @@ describe('ContributionResolver', () => {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('confirm same contribution again', () => {
|
||||||
|
it('throws an error', async () => {
|
||||||
|
await expect(
|
||||||
|
mutate({
|
||||||
|
mutation: confirmContribution,
|
||||||
|
variables: {
|
||||||
|
id: creation ? creation.id : -1,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
).resolves.toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
errors: [new GraphQLError('Contribution already confirmd.')],
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('confirm two creations one after the other quickly', () => {
|
describe('confirm two creations one after the other quickly', () => {
|
||||||
@ -1959,6 +1988,10 @@ describe('ContributionResolver', () => {
|
|||||||
new Date(now.getFullYear(), now.getMonth() - 2, 1),
|
new Date(now.getFullYear(), now.getMonth() - 2, 1),
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
|
await query({
|
||||||
|
query: login,
|
||||||
|
variables: { email: 'peter@lustig.de', password: 'Aa12345_' },
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('throws no error for the second confirmation', async () => {
|
it('throws no error for the second confirmation', async () => {
|
||||||
|
|||||||
@ -553,12 +553,20 @@ export class ContributionResolver {
|
|||||||
@Arg('id', () => Int) id: number,
|
@Arg('id', () => Int) id: number,
|
||||||
@Ctx() context: Context,
|
@Ctx() context: Context,
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
|
// acquire lock
|
||||||
|
const releaseLock = await TRANSACTIONS_LOCK.acquire()
|
||||||
|
|
||||||
|
try {
|
||||||
const clientTimezoneOffset = getClientTimezoneOffset(context)
|
const clientTimezoneOffset = getClientTimezoneOffset(context)
|
||||||
const contribution = await DbContribution.findOne(id)
|
const contribution = await DbContribution.findOne(id)
|
||||||
if (!contribution) {
|
if (!contribution) {
|
||||||
logger.error(`Contribution not found for given id: ${id}`)
|
logger.error(`Contribution not found for given id: ${id}`)
|
||||||
throw new Error('Contribution not found to given id.')
|
throw new Error('Contribution not found to given id.')
|
||||||
}
|
}
|
||||||
|
if (contribution.confirmedAt) {
|
||||||
|
logger.error(`Contribution already confirmd: ${id}`)
|
||||||
|
throw new Error('Contribution already confirmd.')
|
||||||
|
}
|
||||||
const moderatorUser = getUser(context)
|
const moderatorUser = getUser(context)
|
||||||
if (moderatorUser.id === contribution.userId) {
|
if (moderatorUser.id === contribution.userId) {
|
||||||
logger.error('Moderator can not confirm own contribution')
|
logger.error('Moderator can not confirm own contribution')
|
||||||
@ -580,9 +588,6 @@ export class ContributionResolver {
|
|||||||
clientTimezoneOffset,
|
clientTimezoneOffset,
|
||||||
)
|
)
|
||||||
|
|
||||||
// acquire lock
|
|
||||||
const releaseLock = await TRANSACTIONS_LOCK.acquire()
|
|
||||||
|
|
||||||
const receivedCallDate = new Date()
|
const receivedCallDate = new Date()
|
||||||
const queryRunner = getConnection().createQueryRunner()
|
const queryRunner = getConnection().createQueryRunner()
|
||||||
await queryRunner.connect()
|
await queryRunner.connect()
|
||||||
@ -646,7 +651,6 @@ export class ContributionResolver {
|
|||||||
throw new Error('Creation was not successful.')
|
throw new Error('Creation was not successful.')
|
||||||
} finally {
|
} finally {
|
||||||
await queryRunner.release()
|
await queryRunner.release()
|
||||||
releaseLock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const event = new Event()
|
const event = new Event()
|
||||||
@ -655,6 +659,10 @@ export class ContributionResolver {
|
|||||||
eventContributionConfirm.amount = contribution.amount
|
eventContributionConfirm.amount = contribution.amount
|
||||||
eventContributionConfirm.contributionId = contribution.id
|
eventContributionConfirm.contributionId = contribution.id
|
||||||
await eventProtocol.writeEvent(event.setEventContributionConfirm(eventContributionConfirm))
|
await eventProtocol.writeEvent(event.setEventContributionConfirm(eventContributionConfirm))
|
||||||
|
} finally {
|
||||||
|
releaseLock()
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -211,7 +211,7 @@ export class TransactionResolver {
|
|||||||
// find current balance
|
// find current balance
|
||||||
const lastTransaction = await dbTransaction.findOne(
|
const lastTransaction = await dbTransaction.findOne(
|
||||||
{ userId: user.id },
|
{ userId: user.id },
|
||||||
{ order: { balanceDate: 'DESC' }, relations: ['contribution'] },
|
{ order: { id: 'DESC' }, relations: ['contribution'] },
|
||||||
)
|
)
|
||||||
logger.debug(`lastTransaction=${lastTransaction}`)
|
logger.debug(`lastTransaction=${lastTransaction}`)
|
||||||
|
|
||||||
|
|||||||
@ -63,6 +63,7 @@ jest.mock('@/emails/sendEmailVariants', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
jest.mock('@/apis/KlicktippController', () => {
|
jest.mock('@/apis/KlicktippController', () => {
|
||||||
return {
|
return {
|
||||||
__esModule: true,
|
__esModule: true,
|
||||||
@ -132,6 +133,8 @@ describe('UserResolver', () => {
|
|||||||
{
|
{
|
||||||
id: expect.any(Number),
|
id: expect.any(Number),
|
||||||
gradidoID: expect.any(String),
|
gradidoID: expect.any(String),
|
||||||
|
hideAmountGDD: expect.any(Boolean),
|
||||||
|
hideAmountGDT: expect.any(Boolean),
|
||||||
alias: null,
|
alias: null,
|
||||||
emailContact: expect.any(UserContact), // 'peter@lustig.de',
|
emailContact: expect.any(UserContact), // 'peter@lustig.de',
|
||||||
emailId: expect.any(Number),
|
emailId: expect.any(Number),
|
||||||
|
|||||||
@ -567,7 +567,15 @@ export class UserResolver {
|
|||||||
@Mutation(() => Boolean)
|
@Mutation(() => Boolean)
|
||||||
async updateUserInfos(
|
async updateUserInfos(
|
||||||
@Args()
|
@Args()
|
||||||
{ firstName, lastName, language, password, passwordNew }: UpdateUserInfosArgs,
|
{
|
||||||
|
firstName,
|
||||||
|
lastName,
|
||||||
|
language,
|
||||||
|
password,
|
||||||
|
passwordNew,
|
||||||
|
hideAmountGDD,
|
||||||
|
hideAmountGDT,
|
||||||
|
}: UpdateUserInfosArgs,
|
||||||
@Ctx() context: Context,
|
@Ctx() context: Context,
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
logger.info(`updateUserInfos(${firstName}, ${lastName}, ${language}, ***, ***)...`)
|
logger.info(`updateUserInfos(${firstName}, ${lastName}, ${language}, ***, ***)...`)
|
||||||
@ -609,6 +617,15 @@ export class UserResolver {
|
|||||||
userEntity.password = encryptPassword(userEntity, passwordNew)
|
userEntity.password = encryptPassword(userEntity, passwordNew)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save hideAmountGDD value
|
||||||
|
if (hideAmountGDD !== undefined) {
|
||||||
|
userEntity.hideAmountGDD = hideAmountGDD
|
||||||
|
}
|
||||||
|
// Save hideAmountGDT value
|
||||||
|
if (hideAmountGDT !== undefined) {
|
||||||
|
userEntity.hideAmountGDT = hideAmountGDT
|
||||||
|
}
|
||||||
|
|
||||||
const queryRunner = getConnection().createQueryRunner()
|
const queryRunner = getConnection().createQueryRunner()
|
||||||
await queryRunner.connect()
|
await queryRunner.connect()
|
||||||
await queryRunner.startTransaction('REPEATABLE READ')
|
await queryRunner.startTransaction('REPEATABLE READ')
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||||
|
|
||||||
import { backendLogger as logger } from '@/server/logger'
|
import { login, createContribution, confirmContribution } from '@/seeds/graphql/mutations'
|
||||||
import { login, adminCreateContribution, confirmContribution } from '@/seeds/graphql/mutations'
|
|
||||||
import { CreationInterface } from '@/seeds/creation/CreationInterface'
|
import { CreationInterface } from '@/seeds/creation/CreationInterface'
|
||||||
import { ApolloServerTestClient } from 'apollo-server-testing'
|
import { ApolloServerTestClient } from 'apollo-server-testing'
|
||||||
import { Transaction } from '@entity/Transaction'
|
import { Transaction } from '@entity/Transaction'
|
||||||
@ -19,43 +18,27 @@ export const creationFactory = async (
|
|||||||
creation: CreationInterface,
|
creation: CreationInterface,
|
||||||
): Promise<Contribution | void> => {
|
): Promise<Contribution | void> => {
|
||||||
const { mutate } = client
|
const { mutate } = client
|
||||||
logger.trace('creationFactory...')
|
await mutate({ mutation: login, variables: { email: creation.email, password: 'Aa12345_' } })
|
||||||
await mutate({ mutation: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' } })
|
|
||||||
logger.trace('creationFactory... after login')
|
|
||||||
// TODO it would be nice to have this mutation return the id
|
|
||||||
await mutate({ mutation: adminCreateContribution, variables: { ...creation } })
|
|
||||||
logger.trace('creationFactory... after adminCreateContribution')
|
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: { createContribution: contribution },
|
||||||
|
} = await mutate({ mutation: createContribution, variables: { ...creation } })
|
||||||
|
|
||||||
|
if (creation.confirmed) {
|
||||||
const user = await findUserByEmail(creation.email) // userContact.user
|
const user = await findUserByEmail(creation.email) // userContact.user
|
||||||
|
|
||||||
const pendingCreation = await Contribution.findOneOrFail({
|
await mutate({ mutation: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' } })
|
||||||
where: { userId: user.id, amount: creation.amount },
|
await mutate({ mutation: confirmContribution, variables: { id: contribution.id } })
|
||||||
order: { createdAt: 'DESC' },
|
const confirmedContribution = await Contribution.findOneOrFail({ id: contribution.id })
|
||||||
})
|
|
||||||
logger.trace(
|
|
||||||
'creationFactory... after Contribution.findOneOrFail pendingCreation=',
|
|
||||||
pendingCreation,
|
|
||||||
)
|
|
||||||
if (creation.confirmed) {
|
|
||||||
logger.trace('creationFactory... creation.confirmed=', creation.confirmed)
|
|
||||||
await mutate({ mutation: confirmContribution, variables: { id: pendingCreation.id } })
|
|
||||||
logger.trace('creationFactory... after confirmContribution')
|
|
||||||
const confirmedCreation = await Contribution.findOneOrFail({ id: pendingCreation.id })
|
|
||||||
logger.trace(
|
|
||||||
'creationFactory... after Contribution.findOneOrFail confirmedCreation=',
|
|
||||||
confirmedCreation,
|
|
||||||
)
|
|
||||||
|
|
||||||
if (creation.moveCreationDate) {
|
if (creation.moveCreationDate) {
|
||||||
logger.trace('creationFactory... creation.moveCreationDate=', creation.moveCreationDate)
|
|
||||||
const transaction = await Transaction.findOneOrFail({
|
const transaction = await Transaction.findOneOrFail({
|
||||||
where: { userId: user.id, creationDate: new Date(creation.creationDate) },
|
where: { userId: user.id, creationDate: new Date(creation.creationDate) },
|
||||||
order: { balanceDate: 'DESC' },
|
order: { balanceDate: 'DESC' },
|
||||||
})
|
})
|
||||||
logger.trace('creationFactory... after Transaction.findOneOrFail transaction=', transaction)
|
|
||||||
|
|
||||||
if (transaction.decay.equals(0) && transaction.creationDate) {
|
if (transaction.decay.equals(0) && transaction.creationDate) {
|
||||||
confirmedCreation.contributionDate = new Date(
|
confirmedContribution.contributionDate = new Date(
|
||||||
nMonthsBefore(transaction.creationDate, creation.moveCreationDate),
|
nMonthsBefore(transaction.creationDate, creation.moveCreationDate),
|
||||||
)
|
)
|
||||||
transaction.creationDate = new Date(
|
transaction.creationDate = new Date(
|
||||||
@ -64,17 +47,11 @@ export const creationFactory = async (
|
|||||||
transaction.balanceDate = new Date(
|
transaction.balanceDate = new Date(
|
||||||
nMonthsBefore(transaction.balanceDate, creation.moveCreationDate),
|
nMonthsBefore(transaction.balanceDate, creation.moveCreationDate),
|
||||||
)
|
)
|
||||||
logger.trace('creationFactory... before transaction.save transaction=', transaction)
|
|
||||||
await transaction.save()
|
await transaction.save()
|
||||||
logger.trace(
|
await confirmedContribution.save()
|
||||||
'creationFactory... before confirmedCreation.save confirmedCreation=',
|
|
||||||
confirmedCreation,
|
|
||||||
)
|
|
||||||
await confirmedCreation.save()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.trace('creationFactory... pendingCreation=', pendingCreation)
|
return contribution
|
||||||
return pendingCreation
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,6 +31,8 @@ export const updateUserInfos = gql`
|
|||||||
$password: String
|
$password: String
|
||||||
$passwordNew: String
|
$passwordNew: String
|
||||||
$locale: String
|
$locale: String
|
||||||
|
$hideAmountGDD: Boolean
|
||||||
|
$hideAmountGDT: Boolean
|
||||||
) {
|
) {
|
||||||
updateUserInfos(
|
updateUserInfos(
|
||||||
firstName: $firstName
|
firstName: $firstName
|
||||||
@ -38,6 +40,8 @@ export const updateUserInfos = gql`
|
|||||||
password: $password
|
password: $password
|
||||||
passwordNew: $passwordNew
|
passwordNew: $passwordNew
|
||||||
language: $locale
|
language: $locale
|
||||||
|
hideAmountGDD: $hideAmountGDD
|
||||||
|
hideAmountGDT: $hideAmountGDT
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|||||||
@ -18,6 +18,8 @@ const communityDbUser: dbUser = {
|
|||||||
lastName: 'Akademie',
|
lastName: 'Akademie',
|
||||||
deletedAt: null,
|
deletedAt: null,
|
||||||
password: BigInt(0),
|
password: BigInt(0),
|
||||||
|
hideAmountGDD: false,
|
||||||
|
hideAmountGDT: false,
|
||||||
// emailHash: Buffer.from(''),
|
// emailHash: Buffer.from(''),
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
// emailChecked: false,
|
// emailChecked: false,
|
||||||
|
|||||||
@ -1913,9 +1913,9 @@ camelcase@^6.2.0:
|
|||||||
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
|
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
|
||||||
|
|
||||||
caniuse-lite@^1.0.30001264:
|
caniuse-lite@^1.0.30001264:
|
||||||
version "1.0.30001418"
|
version "1.0.30001442"
|
||||||
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz"
|
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001442.tgz"
|
||||||
integrity sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg==
|
integrity sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow==
|
||||||
|
|
||||||
chacha20-universal@^1.0.4:
|
chacha20-universal@^1.0.4:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import {
|
|||||||
DeleteDateColumn,
|
DeleteDateColumn,
|
||||||
OneToOne,
|
OneToOne,
|
||||||
} from 'typeorm'
|
} from 'typeorm'
|
||||||
import { User } from './User'
|
import { User } from '../User'
|
||||||
|
|
||||||
@Entity('user_contacts', { engine: 'InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci' })
|
@Entity('user_contacts', { engine: 'InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci' })
|
||||||
export class UserContact extends BaseEntity {
|
export class UserContact extends BaseEntity {
|
||||||
|
|||||||
118
database/entity/0059-add_hide_amount_to_users/User.ts
Normal file
118
database/entity/0059-add_hide_amount_to_users/User.ts
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
import {
|
||||||
|
BaseEntity,
|
||||||
|
Entity,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
Column,
|
||||||
|
DeleteDateColumn,
|
||||||
|
OneToMany,
|
||||||
|
JoinColumn,
|
||||||
|
OneToOne,
|
||||||
|
} from 'typeorm'
|
||||||
|
import { Contribution } from '../Contribution'
|
||||||
|
import { ContributionMessage } from '../ContributionMessage'
|
||||||
|
import { UserContact } from '../UserContact'
|
||||||
|
|
||||||
|
@Entity('users', { engine: 'InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci' })
|
||||||
|
export class User extends BaseEntity {
|
||||||
|
@PrimaryGeneratedColumn('increment', { unsigned: true })
|
||||||
|
id: number
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'gradido_id',
|
||||||
|
length: 36,
|
||||||
|
nullable: false,
|
||||||
|
collation: 'utf8mb4_unicode_ci',
|
||||||
|
})
|
||||||
|
gradidoID: string
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'alias',
|
||||||
|
length: 20,
|
||||||
|
nullable: true,
|
||||||
|
default: null,
|
||||||
|
collation: 'utf8mb4_unicode_ci',
|
||||||
|
})
|
||||||
|
alias: string
|
||||||
|
|
||||||
|
@OneToOne(() => UserContact, (emailContact: UserContact) => emailContact.user)
|
||||||
|
@JoinColumn({ name: 'email_id' })
|
||||||
|
emailContact: UserContact
|
||||||
|
|
||||||
|
@Column({ name: 'email_id', type: 'int', unsigned: true, nullable: true, default: null })
|
||||||
|
emailId: number | null
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'first_name',
|
||||||
|
length: 255,
|
||||||
|
nullable: true,
|
||||||
|
default: null,
|
||||||
|
collation: 'utf8mb4_unicode_ci',
|
||||||
|
})
|
||||||
|
firstName: string
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'last_name',
|
||||||
|
length: 255,
|
||||||
|
nullable: true,
|
||||||
|
default: null,
|
||||||
|
collation: 'utf8mb4_unicode_ci',
|
||||||
|
})
|
||||||
|
lastName: string
|
||||||
|
|
||||||
|
@Column({ name: 'created_at', default: () => 'CURRENT_TIMESTAMP', nullable: false })
|
||||||
|
createdAt: Date
|
||||||
|
|
||||||
|
@DeleteDateColumn({ name: 'deleted_at', nullable: true })
|
||||||
|
deletedAt: Date | null
|
||||||
|
|
||||||
|
@Column({ type: 'bigint', default: 0, unsigned: true })
|
||||||
|
password: BigInt
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'password_encryption_type',
|
||||||
|
type: 'int',
|
||||||
|
unsigned: true,
|
||||||
|
nullable: false,
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
passwordEncryptionType: number
|
||||||
|
|
||||||
|
@Column({ length: 4, default: 'de', collation: 'utf8mb4_unicode_ci', nullable: false })
|
||||||
|
language: string
|
||||||
|
|
||||||
|
@Column({ type: 'bool', default: false })
|
||||||
|
hideAmountGDD: boolean
|
||||||
|
|
||||||
|
@Column({ type: 'bool', default: false })
|
||||||
|
hideAmountGDT: boolean
|
||||||
|
|
||||||
|
@Column({ name: 'is_admin', type: 'datetime', nullable: true, default: null })
|
||||||
|
isAdmin: Date | null
|
||||||
|
|
||||||
|
@Column({ name: 'referrer_id', type: 'int', unsigned: true, nullable: true, default: null })
|
||||||
|
referrerId?: number | null
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'contribution_link_id',
|
||||||
|
type: 'int',
|
||||||
|
unsigned: true,
|
||||||
|
nullable: true,
|
||||||
|
default: null,
|
||||||
|
})
|
||||||
|
contributionLinkId?: number | null
|
||||||
|
|
||||||
|
@Column({ name: 'publisher_id', default: 0 })
|
||||||
|
publisherId: number
|
||||||
|
|
||||||
|
@OneToMany(() => Contribution, (contribution) => contribution.user)
|
||||||
|
@JoinColumn({ name: 'user_id' })
|
||||||
|
contributions?: Contribution[]
|
||||||
|
|
||||||
|
@OneToMany(() => ContributionMessage, (message) => message.user)
|
||||||
|
@JoinColumn({ name: 'user_id' })
|
||||||
|
messages?: ContributionMessage[]
|
||||||
|
|
||||||
|
@OneToMany(() => UserContact, (userContact: UserContact) => userContact.user)
|
||||||
|
@JoinColumn({ name: 'user_id' })
|
||||||
|
userContacts?: UserContact[]
|
||||||
|
}
|
||||||
@ -1 +1 @@
|
|||||||
export { User } from './0057-clear_old_password_junk/User'
|
export { User } from './0059-add_hide_amount_to_users/User'
|
||||||
|
|||||||
12
database/migrations/0059-add_hide_amount_to_users.ts
Normal file
12
database/migrations/0059-add_hide_amount_to_users.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
|
||||||
|
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
||||||
|
await queryFn('ALTER TABLE users ADD COLUMN hideAmountGDD bool DEFAULT false;')
|
||||||
|
await queryFn('ALTER TABLE users ADD COLUMN hideAmountGDT bool DEFAULT false;')
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
||||||
|
await queryFn('ALTER TABLE users DROP COLUMN hideAmountGDD;')
|
||||||
|
await queryFn('ALTER TABLE users DROP COLUMN hideAmountGDT;')
|
||||||
|
}
|
||||||
@ -112,6 +112,17 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- /sessions
|
- /sessions
|
||||||
|
|
||||||
|
########################################################
|
||||||
|
# MAILSERVER TO FAKE SMTP ##############################
|
||||||
|
########################################################
|
||||||
|
mailserver:
|
||||||
|
image: maildev/maildev
|
||||||
|
ports:
|
||||||
|
- 1080:1080
|
||||||
|
- 1025:1025
|
||||||
|
networks:
|
||||||
|
- external-net
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
frontend_node_modules:
|
frontend_node_modules:
|
||||||
admin_node_modules:
|
admin_node_modules:
|
||||||
|
|||||||
@ -81,6 +81,17 @@ services:
|
|||||||
nginx:
|
nginx:
|
||||||
image: gradido/nginx:test
|
image: gradido/nginx:test
|
||||||
|
|
||||||
|
########################################################
|
||||||
|
# MAILSERVER TO FAKE SMTP ##############################
|
||||||
|
########################################################
|
||||||
|
mailserver:
|
||||||
|
image: maildev/maildev
|
||||||
|
ports:
|
||||||
|
- 1080:1080
|
||||||
|
- 1025:1025
|
||||||
|
networks:
|
||||||
|
- external-net
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
external-net:
|
external-net:
|
||||||
internal-net:
|
internal-net:
|
||||||
|
|||||||
@ -37,7 +37,7 @@
|
|||||||
</b-row>
|
</b-row>
|
||||||
<b-row class="mt-5 p-5">
|
<b-row class="mt-5 p-5">
|
||||||
<b-col>
|
<b-col>
|
||||||
<b-button @click="$emit('on-reset')">{{ $t('back') }}</b-button>
|
<b-button @click="$emit('on-back')">{{ $t('back') }}</b-button>
|
||||||
</b-col>
|
</b-col>
|
||||||
<b-col class="text-right">
|
<b-col class="text-right">
|
||||||
<b-button
|
<b-button
|
||||||
|
|||||||
@ -41,7 +41,7 @@
|
|||||||
</b-row>
|
</b-row>
|
||||||
<b-row class="mt-5 p-5">
|
<b-row class="mt-5 p-5">
|
||||||
<b-col>
|
<b-col>
|
||||||
<b-button @click="$emit('on-reset')">{{ $t('back') }}</b-button>
|
<b-button @click="$emit('on-back')">{{ $t('back') }}</b-button>
|
||||||
</b-col>
|
</b-col>
|
||||||
<b-col class="text-right">
|
<b-col class="text-right">
|
||||||
<b-button
|
<b-button
|
||||||
|
|||||||
@ -322,7 +322,7 @@ Die ganze Welt bezwingen.“`)
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
email: 'someone@watches.tv',
|
email: 'someone@watches.tv',
|
||||||
amount: '87.23',
|
amount: 87.23,
|
||||||
memo: 'Long enough',
|
memo: 'Long enough',
|
||||||
selected: 'send',
|
selected: 'send',
|
||||||
},
|
},
|
||||||
|
|||||||
@ -144,7 +144,7 @@ export default {
|
|||||||
this.$emit('set-transaction', {
|
this.$emit('set-transaction', {
|
||||||
selected: this.radioSelected,
|
selected: this.radioSelected,
|
||||||
email: this.form.email,
|
email: this.form.email,
|
||||||
amount: this.form.amount,
|
amount: Number(this.form.amount.replace(',', '.')),
|
||||||
memo: this.form.memo,
|
memo: this.form.memo,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<div><figure-qr-code :link="link" /></div>
|
<div><figure-qr-code :link="link" /></div>
|
||||||
<div>
|
<div>
|
||||||
<b-button variant="secondary" @click="$emit('on-reset')" class="mt-4" data-test="close-btn">
|
<b-button variant="secondary" @click="$emit('on-back')" class="mt-4" data-test="close-btn">
|
||||||
{{ $t('form.close') }}
|
{{ $t('form.close') }}
|
||||||
</b-button>
|
</b-button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
{{ $t('form.send_transaction_success') }}
|
{{ $t('form.send_transaction_success') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center mt-5">
|
<div class="text-center mt-5">
|
||||||
<b-button variant="primary" @click="$emit('on-reset')">{{ $t('form.close') }}</b-button>
|
<b-button variant="primary" @click="$emit('on-back')">{{ $t('form.close') }}</b-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -40,11 +40,11 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
name: { type: String, default: 'Email' },
|
name: { type: String, required: true },
|
||||||
label: { type: String, default: 'Email' },
|
label: { type: String, required: true },
|
||||||
placeholder: { type: String, default: 'Email' },
|
placeholder: { type: String, required: true },
|
||||||
value: { required: true, type: String, default: '' },
|
value: { type: String, required: true },
|
||||||
disabled: { required: false, type: Boolean, default: false },
|
disabled: { type: Boolean, required: false, default: false },
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -12,14 +12,20 @@
|
|||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
</b-button>
|
</b-button>
|
||||||
</b-navbar-brand>
|
</b-navbar-brand>
|
||||||
<b-img class="sheet-img position-absolute zindex1" :src="sheet"></b-img>
|
|
||||||
<router-link to="/settings" class="d-block d-lg-none zindex1000">
|
<router-link to="/settings" class="d-block d-lg-none">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<div class="mr-3">
|
<div class="mr-3">
|
||||||
<avatar :username="username.username" :color="'#fff'" :size="61"></avatar>
|
<avatar
|
||||||
|
:username="username.username"
|
||||||
|
:initials="username.initials"
|
||||||
|
:color="'#fff'"
|
||||||
|
:size="61"
|
||||||
|
></avatar>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
<b-img class="sheet-img position-absolute zindex-1" :src="sheet"></b-img>
|
||||||
<b-collapse id="nav-collapse" is-nav class="ml-5">
|
<b-collapse id="nav-collapse" is-nav class="ml-5">
|
||||||
<b-navbar-nav class="ml-auto" right>
|
<b-navbar-nav class="ml-auto" right>
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
|
|||||||
@ -1,20 +1,31 @@
|
|||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import GddAmount from './GddAmount'
|
import GddAmount from './GddAmount'
|
||||||
|
import { updateUserInfos } from '@/graphql/mutations'
|
||||||
|
import flushPromises from 'flush-promises'
|
||||||
|
|
||||||
|
import { toastErrorSpy, toastSuccessSpy } from '@test/testSetup'
|
||||||
|
|
||||||
const localVue = global.localVue
|
const localVue = global.localVue
|
||||||
|
|
||||||
|
const mockAPICall = jest.fn()
|
||||||
|
const storeCommitMock = jest.fn()
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
language: 'en',
|
hideAmountGDD: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
const mocks = {
|
const mocks = {
|
||||||
$store: {
|
$store: {
|
||||||
state,
|
state,
|
||||||
|
commit: storeCommitMock,
|
||||||
},
|
},
|
||||||
$i18n: {
|
$i18n: {
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
},
|
},
|
||||||
$t: jest.fn((t) => t),
|
$t: jest.fn((t) => t),
|
||||||
|
$apollo: {
|
||||||
|
mutate: mockAPICall,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const propsData = {
|
const propsData = {
|
||||||
@ -38,5 +49,89 @@ describe('GddAmount', () => {
|
|||||||
it('renders the component gdd-amount', () => {
|
it('renders the component gdd-amount', () => {
|
||||||
expect(wrapper.find('div.gdd-amount').exists()).toBe(true)
|
expect(wrapper.find('div.gdd-amount').exists()).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('API throws exception', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
mockAPICall.mockRejectedValue({
|
||||||
|
message: 'Ouch',
|
||||||
|
})
|
||||||
|
jest.clearAllMocks()
|
||||||
|
await wrapper.find('div.border-left svg').trigger('click')
|
||||||
|
await flushPromises()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('toasts an error message', () => {
|
||||||
|
expect(toastErrorSpy).toBeCalledWith('Ouch')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('API call successful', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
mockAPICall.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
updateUserInfos: {
|
||||||
|
validValues: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
jest.clearAllMocks()
|
||||||
|
await wrapper.find('div.border-left svg').trigger('click')
|
||||||
|
await flushPromises()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('calls the API', () => {
|
||||||
|
expect(mockAPICall).toBeCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
mutation: updateUserInfos,
|
||||||
|
variables: {
|
||||||
|
hideAmountGDD: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('commits hideAmountGDD to store', () => {
|
||||||
|
expect(storeCommitMock).toBeCalledWith('hideAmountGDD', true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('toasts a success message', () => {
|
||||||
|
expect(toastSuccessSpy).toBeCalledWith('settings.showAmountGDD')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('second call to API', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
mockAPICall.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
updateUserInfos: {
|
||||||
|
validValues: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
jest.clearAllMocks()
|
||||||
|
wrapper.vm.$store.state.hideAmountGDD = true
|
||||||
|
await wrapper.find('div.border-left svg').trigger('click')
|
||||||
|
await flushPromises()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('calls the API', () => {
|
||||||
|
expect(mockAPICall).toBeCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
mutation: updateUserInfos,
|
||||||
|
variables: {
|
||||||
|
hideAmountGDD: false,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('commits hideAmountGDD to store', () => {
|
||||||
|
expect(storeCommitMock).toBeCalledWith('hideAmountGDD', false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('toasts a success message', () => {
|
||||||
|
expect(toastSuccessSpy).toBeCalledWith('settings.hideAmountGDD')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -39,7 +39,7 @@
|
|||||||
<b-icon
|
<b-icon
|
||||||
:icon="hideAmount ? 'eye-slash' : 'eye'"
|
:icon="hideAmount ? 'eye-slash' : 'eye'"
|
||||||
class="mr-3 gradido-global-border-color-accent pointer hover-icon"
|
class="mr-3 gradido-global-border-color-accent pointer hover-icon"
|
||||||
@click="$store.commit('hideAmountGDD', !hideAmount)"
|
@click="updateHideAmountGDD"
|
||||||
></b-icon>
|
></b-icon>
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
@ -47,6 +47,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import { updateUserInfos } from '@/graphql/mutations'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'GddAmount',
|
name: 'GddAmount',
|
||||||
props: {
|
props: {
|
||||||
@ -60,5 +62,27 @@ export default {
|
|||||||
return this.$store.state.hideAmountGDD
|
return this.$store.state.hideAmountGDD
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
async updateHideAmountGDD() {
|
||||||
|
this.$apollo
|
||||||
|
.mutate({
|
||||||
|
mutation: updateUserInfos,
|
||||||
|
variables: {
|
||||||
|
hideAmountGDD: !this.hideAmount,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.$store.commit('hideAmountGDD', !this.hideAmount)
|
||||||
|
if (!this.hideAmount) {
|
||||||
|
this.toastSuccess(this.$t('settings.showAmountGDD'))
|
||||||
|
} else {
|
||||||
|
this.toastSuccess(this.$t('settings.hideAmountGDD'))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.toastError(error.message)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,19 +1,30 @@
|
|||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import GdtAmount from './GdtAmount'
|
import GdtAmount from './GdtAmount'
|
||||||
|
import { updateUserInfos } from '@/graphql/mutations'
|
||||||
|
import flushPromises from 'flush-promises'
|
||||||
|
|
||||||
|
import { toastErrorSpy, toastSuccessSpy } from '@test/testSetup'
|
||||||
|
|
||||||
const localVue = global.localVue
|
const localVue = global.localVue
|
||||||
|
|
||||||
|
const mockAPICall = jest.fn()
|
||||||
|
const storeCommitMock = jest.fn()
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
language: 'en',
|
hideAmountGDT: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
const mocks = {
|
const mocks = {
|
||||||
$store: {
|
$store: {
|
||||||
state,
|
state,
|
||||||
|
commit: storeCommitMock,
|
||||||
},
|
},
|
||||||
$i18n: {
|
$i18n: {
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
},
|
},
|
||||||
|
$apollo: {
|
||||||
|
mutate: mockAPICall,
|
||||||
|
},
|
||||||
$t: jest.fn((t) => t),
|
$t: jest.fn((t) => t),
|
||||||
$n: jest.fn((n) => n),
|
$n: jest.fn((n) => n),
|
||||||
}
|
}
|
||||||
@ -39,5 +50,89 @@ describe('GdtAmount', () => {
|
|||||||
it('renders the component gdt-amount', () => {
|
it('renders the component gdt-amount', () => {
|
||||||
expect(wrapper.find('div.gdt-amount').exists()).toBe(true)
|
expect(wrapper.find('div.gdt-amount').exists()).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('API throws exception', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
mockAPICall.mockRejectedValue({
|
||||||
|
message: 'Ouch',
|
||||||
|
})
|
||||||
|
jest.clearAllMocks()
|
||||||
|
await wrapper.find('div.border-left svg').trigger('click')
|
||||||
|
await flushPromises()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('toasts an error message', () => {
|
||||||
|
expect(toastErrorSpy).toBeCalledWith('Ouch')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('API call successful', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
mockAPICall.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
updateUserInfos: {
|
||||||
|
validValues: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
jest.clearAllMocks()
|
||||||
|
await wrapper.find('div.border-left svg').trigger('click')
|
||||||
|
await flushPromises()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('calls the API', () => {
|
||||||
|
expect(mockAPICall).toBeCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
mutation: updateUserInfos,
|
||||||
|
variables: {
|
||||||
|
hideAmountGDT: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('commits hideAmountGDT to store', () => {
|
||||||
|
expect(storeCommitMock).toBeCalledWith('hideAmountGDT', true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('toasts a success message', () => {
|
||||||
|
expect(toastSuccessSpy).toBeCalledWith('settings.showAmountGDT')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('second call to API', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
mockAPICall.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
updateUserInfos: {
|
||||||
|
validValues: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
jest.clearAllMocks()
|
||||||
|
wrapper.vm.$store.state.hideAmountGDT = true
|
||||||
|
await wrapper.find('div.border-left svg').trigger('click')
|
||||||
|
await flushPromises()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('calls the API', () => {
|
||||||
|
expect(mockAPICall).toBeCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
mutation: updateUserInfos,
|
||||||
|
variables: {
|
||||||
|
hideAmountGDT: false,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('commits hideAmountGDT to store', () => {
|
||||||
|
expect(storeCommitMock).toBeCalledWith('hideAmountGDT', false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('toasts a success message', () => {
|
||||||
|
expect(toastSuccessSpy).toBeCalledWith('settings.hideAmountGDT')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
<b-icon
|
<b-icon
|
||||||
:icon="hideAmount ? 'eye-slash' : 'eye'"
|
:icon="hideAmount ? 'eye-slash' : 'eye'"
|
||||||
class="mr-3 gradido-global-border-color-accent pointer hover-icon"
|
class="mr-3 gradido-global-border-color-accent pointer hover-icon"
|
||||||
@click="$store.commit('hideAmountGDT', !hideAmount)"
|
@click="updateHideAmountGDT"
|
||||||
></b-icon>
|
></b-icon>
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
@ -42,6 +42,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import { updateUserInfos } from '@/graphql/mutations'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'GdtAmount',
|
name: 'GdtAmount',
|
||||||
props: {
|
props: {
|
||||||
@ -54,5 +56,27 @@ export default {
|
|||||||
return this.$store.state.hideAmountGDT
|
return this.$store.state.hideAmountGDT
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
async updateHideAmountGDT() {
|
||||||
|
this.$apollo
|
||||||
|
.mutate({
|
||||||
|
mutation: updateUserInfos,
|
||||||
|
variables: {
|
||||||
|
hideAmountGDT: !this.hideAmount,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.$store.commit('hideAmountGDT', !this.hideAmount)
|
||||||
|
if (!this.hideAmount) {
|
||||||
|
this.toastSuccess(this.$t('settings.showAmountGDT'))
|
||||||
|
} else {
|
||||||
|
this.toastSuccess(this.$t('settings.hideAmountGDT'))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.toastError(error.message)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -24,6 +24,7 @@
|
|||||||
:size="72"
|
:size="72"
|
||||||
:color="'#fff'"
|
:color="'#fff'"
|
||||||
:username="`${transaction.linkedUser.firstName} ${transaction.linkedUser.lastName}`"
|
:username="`${transaction.linkedUser.firstName} ${transaction.linkedUser.lastName}`"
|
||||||
|
:initials="`${transaction.linkedUser.firstName[0]} ${transaction.linkedUser.lastName[0]}`"
|
||||||
></avatar>
|
></avatar>
|
||||||
</div>
|
</div>
|
||||||
</b-col>
|
</b-col>
|
||||||
|
|||||||
@ -31,6 +31,8 @@ export const updateUserInfos = gql`
|
|||||||
$password: String
|
$password: String
|
||||||
$passwordNew: String
|
$passwordNew: String
|
||||||
$locale: String
|
$locale: String
|
||||||
|
$hideAmountGDD: Boolean
|
||||||
|
$hideAmountGDT: Boolean
|
||||||
) {
|
) {
|
||||||
updateUserInfos(
|
updateUserInfos(
|
||||||
firstName: $firstName
|
firstName: $firstName
|
||||||
@ -38,6 +40,8 @@ export const updateUserInfos = gql`
|
|||||||
password: $password
|
password: $password
|
||||||
passwordNew: $passwordNew
|
passwordNew: $passwordNew
|
||||||
language: $locale
|
language: $locale
|
||||||
|
hideAmountGDD: $hideAmountGDD
|
||||||
|
hideAmountGDT: $hideAmountGDT
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
@ -151,6 +155,8 @@ export const login = gql`
|
|||||||
publisherId
|
publisherId
|
||||||
isAdmin
|
isAdmin
|
||||||
creation
|
creation
|
||||||
|
hideAmountGDD
|
||||||
|
hideAmountGDT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|||||||
@ -14,6 +14,8 @@ export const verifyLogin = gql`
|
|||||||
publisherId
|
publisherId
|
||||||
isAdmin
|
isAdmin
|
||||||
creation
|
creation
|
||||||
|
hideAmountGDD
|
||||||
|
hideAmountGDT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|||||||
@ -269,6 +269,8 @@
|
|||||||
"warningText": "Bist du noch da?"
|
"warningText": "Bist du noch da?"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
|
"hideAmountGDD": "Dein GDD Betrag ist versteckt.",
|
||||||
|
"hideAmountGDT": "Dein GDT Betrag ist versteckt.",
|
||||||
"language": {
|
"language": {
|
||||||
"changeLanguage": "Sprache ändern",
|
"changeLanguage": "Sprache ändern",
|
||||||
"de": "Deutsch",
|
"de": "Deutsch",
|
||||||
@ -301,7 +303,9 @@
|
|||||||
"text": "Speichere nun dein neues Passwort, mit dem du dich zukünftig in deinem Gradido-Konto anmelden kannst."
|
"text": "Speichere nun dein neues Passwort, mit dem du dich zukünftig in deinem Gradido-Konto anmelden kannst."
|
||||||
},
|
},
|
||||||
"subtitle": "Wenn du dein Passwort vergessen hast, kannst du es hier zurücksetzen."
|
"subtitle": "Wenn du dein Passwort vergessen hast, kannst du es hier zurücksetzen."
|
||||||
}
|
},
|
||||||
|
"showAmountGDD": "Dein GDD Betrag ist sichtbar.",
|
||||||
|
"showAmountGDT": "Dein GDT Betrag ist sichtbar."
|
||||||
},
|
},
|
||||||
"signin": "Anmelden",
|
"signin": "Anmelden",
|
||||||
"signup": "Registrieren",
|
"signup": "Registrieren",
|
||||||
|
|||||||
@ -269,6 +269,8 @@
|
|||||||
"warningText": "Are you still there?"
|
"warningText": "Are you still there?"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
|
"hideAmountGDD": "Your GDD amount is hidden.",
|
||||||
|
"hideAmountGDT": "Your GDT amount is hidden.",
|
||||||
"language": {
|
"language": {
|
||||||
"changeLanguage": "Change language",
|
"changeLanguage": "Change language",
|
||||||
"de": "Deutsch",
|
"de": "Deutsch",
|
||||||
@ -301,7 +303,9 @@
|
|||||||
"text": "Now save your new password, which you can use to log in to your Gradido account in the future."
|
"text": "Now save your new password, which you can use to log in to your Gradido account in the future."
|
||||||
},
|
},
|
||||||
"subtitle": "If you have forgotten your password, you can reset it here."
|
"subtitle": "If you have forgotten your password, you can reset it here."
|
||||||
}
|
},
|
||||||
|
"showAmountGDD": "Your GDD amount is visible.",
|
||||||
|
"showAmountGDT": "Your GDT amount is visible."
|
||||||
},
|
},
|
||||||
"signin": "Sign in",
|
"signin": "Sign in",
|
||||||
"signup": "Sign up",
|
"signup": "Sign up",
|
||||||
|
|||||||
@ -58,11 +58,11 @@ describe('ForgotPassword', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('has the label "Email"', () => {
|
it('has the label "Email"', () => {
|
||||||
expect(form.find('label').text()).toEqual('Email')
|
expect(form.find('label').text()).toEqual('form.email')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('has the placeholder "Email"', () => {
|
it('has the placeholder "Email"', () => {
|
||||||
expect(form.find('input').attributes('placeholder')).toEqual('Email')
|
expect(form.find('input').attributes('placeholder')).toEqual('form.email')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('has a submit button', () => {
|
it('has a submit button', () => {
|
||||||
|
|||||||
@ -6,7 +6,12 @@
|
|||||||
<b-col>
|
<b-col>
|
||||||
<validation-observer ref="observer" v-slot="{ handleSubmit }">
|
<validation-observer ref="observer" v-slot="{ handleSubmit }">
|
||||||
<b-form role="form" @submit.prevent="handleSubmit(onSubmit)">
|
<b-form role="form" @submit.prevent="handleSubmit(onSubmit)">
|
||||||
<input-email v-model="form.email"></input-email>
|
<input-email
|
||||||
|
v-model="form.email"
|
||||||
|
:name="$t('form.email')"
|
||||||
|
:label="$t('form.email')"
|
||||||
|
:placeholder="$t('form.email')"
|
||||||
|
></input-email>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<b-button type="submit" variant="gradido">
|
<b-button type="submit" variant="gradido">
|
||||||
{{ $t('settings.password.send_now') }}
|
{{ $t('settings.password.send_now') }}
|
||||||
|
|||||||
@ -76,7 +76,7 @@ describe('Login', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('has an Email input field', () => {
|
it('has an Email input field', () => {
|
||||||
expect(wrapper.find('input[placeholder="Email"]').exists()).toBe(true)
|
expect(wrapper.find('div[data-test="input-email"]').find('input').exists()).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('has an Password input field', () => {
|
it('has an Password input field', () => {
|
||||||
@ -110,7 +110,10 @@ describe('Login', () => {
|
|||||||
describe('valid data', () => {
|
describe('valid data', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
await wrapper.find('input[placeholder="Email"]').setValue('user@example.org')
|
await wrapper
|
||||||
|
.find('div[data-test="input-email"]')
|
||||||
|
.find('input')
|
||||||
|
.setValue('user@example.org')
|
||||||
await wrapper.find('input[placeholder="form.password"]').setValue('1234')
|
await wrapper.find('input[placeholder="form.password"]').setValue('1234')
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
apolloMutateMock.mockResolvedValue({
|
apolloMutateMock.mockResolvedValue({
|
||||||
@ -159,7 +162,10 @@ describe('Login', () => {
|
|||||||
code: 'some-code',
|
code: 'some-code',
|
||||||
}
|
}
|
||||||
wrapper = Wrapper()
|
wrapper = Wrapper()
|
||||||
await wrapper.find('input[placeholder="Email"]').setValue('user@example.org')
|
await wrapper
|
||||||
|
.find('div[data-test="input-email"]')
|
||||||
|
.find('input')
|
||||||
|
.setValue('user@example.org')
|
||||||
await wrapper.find('input[placeholder="form.password"]').setValue('1234')
|
await wrapper.find('input[placeholder="form.password"]').setValue('1234')
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
await wrapper.find('form').trigger('submit')
|
await wrapper.find('form').trigger('submit')
|
||||||
@ -180,7 +186,10 @@ describe('Login', () => {
|
|||||||
})
|
})
|
||||||
wrapper = Wrapper()
|
wrapper = Wrapper()
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
await wrapper.find('input[placeholder="Email"]').setValue('user@example.org')
|
await wrapper
|
||||||
|
.find('div[data-test="input-email"]')
|
||||||
|
.find('input')
|
||||||
|
.setValue('user@example.org')
|
||||||
await wrapper.find('input[placeholder="form.password"]').setValue('1234')
|
await wrapper.find('input[placeholder="form.password"]').setValue('1234')
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
await wrapper.find('form').trigger('submit')
|
await wrapper.find('form').trigger('submit')
|
||||||
|
|||||||
@ -5,7 +5,14 @@
|
|||||||
<validation-observer ref="observer" v-slot="{ handleSubmit }">
|
<validation-observer ref="observer" v-slot="{ handleSubmit }">
|
||||||
<b-form @submit.stop.prevent="handleSubmit(onSubmit)">
|
<b-form @submit.stop.prevent="handleSubmit(onSubmit)">
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col sm="12" md="12" lg="6"><input-email v-model="form.email"></input-email></b-col>
|
<b-col sm="12" md="12" lg="6">
|
||||||
|
<input-email
|
||||||
|
v-model="form.email"
|
||||||
|
:name="$t('form.email')"
|
||||||
|
:label="$t('form.email')"
|
||||||
|
:placeholder="$t('form.email')"
|
||||||
|
></input-email>
|
||||||
|
</b-col>
|
||||||
<b-col sm="12" md="12" lg="6">
|
<b-col sm="12" md="12" lg="6">
|
||||||
<input-password
|
<input-password
|
||||||
:label="$t('form.password')"
|
:label="$t('form.password')"
|
||||||
|
|||||||
@ -65,7 +65,7 @@ describe('Register', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('has email input fields', () => {
|
it('has email input fields', () => {
|
||||||
expect(wrapper.find('#Email-input-field').exists()).toBe(true)
|
expect(wrapper.find('div[data-test="input-email"]').find('input').exists()).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('has 1 checkbox input fields', () => {
|
it('has 1 checkbox input fields', () => {
|
||||||
@ -107,7 +107,10 @@ describe('Register', () => {
|
|||||||
wrapper.find('#registerLastname').setValue('Mustermann')
|
wrapper.find('#registerLastname').setValue('Mustermann')
|
||||||
})
|
})
|
||||||
it('has disabled submit button when missing input checked box', () => {
|
it('has disabled submit button when missing input checked box', () => {
|
||||||
wrapper.find('#Email-input-field').setValue('max.mustermann@gradido.net')
|
wrapper
|
||||||
|
.find('div[data-test="input-email"]')
|
||||||
|
.find('input')
|
||||||
|
.setValue('max.mustermann@gradido.net')
|
||||||
expect(wrapper.find('button[type="submit"]').attributes('disabled')).toBe('disabled')
|
expect(wrapper.find('button[type="submit"]').attributes('disabled')).toBe('disabled')
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -121,7 +124,10 @@ describe('Register', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
wrapper.find('#registerFirstname').setValue('Max')
|
wrapper.find('#registerFirstname').setValue('Max')
|
||||||
wrapper.find('#registerLastname').setValue('Mustermann')
|
wrapper.find('#registerLastname').setValue('Mustermann')
|
||||||
wrapper.find('#Email-input-field').setValue('max.mustermann@gradido.net')
|
wrapper
|
||||||
|
.find('div[data-test="input-email"]')
|
||||||
|
.find('input')
|
||||||
|
.setValue('max.mustermann@gradido.net')
|
||||||
wrapper.find('#registerCheckbox').setChecked()
|
wrapper.find('#registerCheckbox').setChecked()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -211,7 +217,10 @@ describe('Register', () => {
|
|||||||
wrapper = Wrapper()
|
wrapper = Wrapper()
|
||||||
wrapper.find('#registerFirstname').setValue('Max')
|
wrapper.find('#registerFirstname').setValue('Max')
|
||||||
wrapper.find('#registerLastname').setValue('Mustermann')
|
wrapper.find('#registerLastname').setValue('Mustermann')
|
||||||
wrapper.find('#Email-input-field').setValue('max.mustermann@gradido.net')
|
wrapper
|
||||||
|
.find('div[data-test="input-email"]')
|
||||||
|
.find('input')
|
||||||
|
.setValue('max.mustermann@gradido.net')
|
||||||
wrapper.find('#registerCheckbox').setChecked()
|
wrapper.find('#registerCheckbox').setChecked()
|
||||||
await wrapper.find('form').trigger('submit')
|
await wrapper.find('form').trigger('submit')
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
|
|||||||
@ -59,7 +59,14 @@
|
|||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col><input-email v-model="form.email"></input-email></b-col>
|
<b-col>
|
||||||
|
<input-email
|
||||||
|
v-model="form.email"
|
||||||
|
:name="$t('form.email')"
|
||||||
|
:label="$t('form.email')"
|
||||||
|
:placeholder="$t('form.email')"
|
||||||
|
></input-email>
|
||||||
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
<div class="my-4">
|
<div class="my-4">
|
||||||
<b-form-checkbox
|
<b-form-checkbox
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
:amount="transactionData.amount"
|
:amount="transactionData.amount"
|
||||||
:memo="transactionData.memo"
|
:memo="transactionData.memo"
|
||||||
@send-transaction="sendTransaction"
|
@send-transaction="sendTransaction"
|
||||||
@on-reset="onReset"
|
@on-back="onBack"
|
||||||
></transaction-confirmation-send>
|
></transaction-confirmation-send>
|
||||||
</template>
|
</template>
|
||||||
<template #transactionConfirmationLink>
|
<template #transactionConfirmationLink>
|
||||||
@ -26,17 +26,17 @@
|
|||||||
:memo="transactionData.memo"
|
:memo="transactionData.memo"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
@send-transaction="sendTransaction"
|
@send-transaction="sendTransaction"
|
||||||
@on-reset="onReset"
|
@on-back="onBack"
|
||||||
></transaction-confirmation-link>
|
></transaction-confirmation-link>
|
||||||
</template>
|
</template>
|
||||||
<template #transactionResultSendSuccess>
|
<template #transactionResultSendSuccess>
|
||||||
<transaction-result-send-success @on-reset="onReset"></transaction-result-send-success>
|
<transaction-result-send-success @on-back="onBack"></transaction-result-send-success>
|
||||||
</template>
|
</template>
|
||||||
<template #transactionResultSendError>
|
<template #transactionResultSendError>
|
||||||
<transaction-result-send-error
|
<transaction-result-send-error
|
||||||
:error="error"
|
:error="error"
|
||||||
:errorResult="errorResult"
|
:errorResult="errorResult"
|
||||||
@on-reset="onReset"
|
@on-back="onBack"
|
||||||
></transaction-result-send-error>
|
></transaction-result-send-error>
|
||||||
</template>
|
</template>
|
||||||
<template #transactionResultLink>
|
<template #transactionResultLink>
|
||||||
@ -45,7 +45,7 @@
|
|||||||
:amount="amount"
|
:amount="amount"
|
||||||
:memo="memo"
|
:memo="memo"
|
||||||
:validUntil="validUntil"
|
:validUntil="validUntil"
|
||||||
@on-reset="onReset"
|
@on-back="onBack"
|
||||||
></transaction-result-link>
|
></transaction-result-link>
|
||||||
</template>
|
</template>
|
||||||
</gdd-send>
|
</gdd-send>
|
||||||
@ -169,8 +169,9 @@ export default {
|
|||||||
}
|
}
|
||||||
this.loading = false
|
this.loading = false
|
||||||
},
|
},
|
||||||
onReset() {
|
onBack() {
|
||||||
this.currentTransactionStep = TRANSACTION_STEPS.transactionForm
|
this.currentTransactionStep = TRANSACTION_STEPS.transactionForm
|
||||||
|
this.$mount()
|
||||||
},
|
},
|
||||||
updateTransactions(pagination) {
|
updateTransactions(pagination) {
|
||||||
this.$emit('update-transactions', pagination)
|
this.$emit('update-transactions', pagination)
|
||||||
|
|||||||
@ -85,7 +85,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
gdt() {
|
currentPage() {
|
||||||
if (this.gdt) {
|
if (this.gdt) {
|
||||||
this.updateGdt()
|
this.updateGdt()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4578,9 +4578,9 @@ caniuse-api@^3.0.0:
|
|||||||
lodash.uniq "^4.5.0"
|
lodash.uniq "^4.5.0"
|
||||||
|
|
||||||
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001181, caniuse-lite@^1.0.30001280, caniuse-lite@^1.0.30001286:
|
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001181, caniuse-lite@^1.0.30001280, caniuse-lite@^1.0.30001286:
|
||||||
version "1.0.30001439"
|
version "1.0.30001442"
|
||||||
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz"
|
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001442.tgz"
|
||||||
integrity sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==
|
integrity sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow==
|
||||||
|
|
||||||
capture-exit@^2.0.0:
|
capture-exit@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user