Merge branch 'master' into database_admin_pending_creations_decimal

This commit is contained in:
Ulf Gebhardt 2022-04-25 14:08:00 +02:00 committed by GitHub
commit e9906f3908
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 443 additions and 184 deletions

View File

@ -14,7 +14,7 @@
"analyse-bundle": "yarn build && webpack-bundle-analyzer dist/webpack.stats.json",
"lint": "eslint --max-warnings=0 --ext .js,.vue,.json .",
"stylelint": "stylelint --max-warnings=0 '**/*.{scss,vue}'",
"test": "TZ=UTC jest --coverage",
"test": "cross-env TZ=UTC jest --coverage",
"locales": "scripts/sort.sh"
},
"dependencies": {
@ -57,6 +57,7 @@
"@vue/cli-service": "~4.5.0",
"babel-eslint": "^10.1.0",
"babel-plugin-transform-require-context": "^0.1.1",
"cross-env": "^7.0.3",
"eslint": "7.25.0",
"eslint-config-prettier": "^8.3.0",
"eslint-config-standard": "^16.0.3",

View File

@ -4688,6 +4688,13 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
cross-env@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf"
integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==
dependencies:
cross-spawn "^7.0.1"
cross-spawn@^5.0.1:
version "5.1.0"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
@ -4708,7 +4715,7 @@ cross-spawn@^6.0.0:
shebang-command "^1.2.0"
which "^1.2.9"
cross-spawn@^7.0.0, cross-spawn@^7.0.2:
cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==

View File

@ -1,4 +1,4 @@
CONFIG_VERSION=v5.2022-04-12
CONFIG_VERSION=v6.2022-04-21
# Server
PORT=4000
@ -27,6 +27,7 @@ KLICKTIPP_APIKEY_EN=SomeFakeKeyEN
COMMUNITY_NAME=Gradido Entwicklung
COMMUNITY_URL=http://localhost/
COMMUNITY_REGISTER_URL=http://localhost/register
COMMUNITY_REDEEM_URL=http://localhost/redeem/{code}
COMMUNITY_DESCRIPTION=Die lokale Entwicklungsumgebung von Gradido.
# Login Server

View File

@ -26,6 +26,7 @@ KLICKTIPP_APIKEY_EN=$KLICKTIPP_APIKEY_EN
COMMUNITY_NAME=$COMMUNITY_NAME
COMMUNITY_URL=$COMMUNITY_URL
COMMUNITY_REGISTER_URL=$COMMUNITY_REGISTER_URL
COMMUNITY_REDEEM_URL=$COMMUNITY_REDEEM_URL
COMMUNITY_DESCRIPTION=$COMMUNITY_DESCRIPTION
# Login Server

View File

@ -10,11 +10,11 @@
"scripts": {
"build": "tsc --build",
"clean": "tsc --build --clean",
"start": "TZ=UTC TS_NODE_BASEURL=./build node -r tsconfig-paths/register build/src/index.js",
"dev": "TZ=UTC nodemon -w src --ext ts --exec ts-node -r tsconfig-paths/register src/index.ts",
"start": "cross-env TZ=UTC TS_NODE_BASEURL=./build node -r tsconfig-paths/register build/src/index.js",
"dev": "cross-env TZ=UTC nodemon -w src --ext ts --exec ts-node -r tsconfig-paths/register src/index.ts",
"lint": "eslint --max-warnings=0 --ext .js,.ts .",
"test": "TZ=UTC NODE_ENV=development jest --runInBand --coverage --forceExit --detectOpenHandles",
"seed": "TZ=UTC ts-node -r tsconfig-paths/register src/seeds/index.ts"
"test": "cross-env TZ=UTC NODE_ENV=development jest --runInBand --coverage --forceExit --detectOpenHandles",
"seed": "cross-env TZ=UTC ts-node -r tsconfig-paths/register src/seeds/index.ts"
},
"dependencies": {
"@types/jest": "^27.0.2",
@ -25,6 +25,7 @@
"axios": "^0.21.1",
"class-validator": "^0.13.1",
"cors": "^2.8.5",
"cross-env": "^7.0.3",
"decimal.js-light": "^2.5.1",
"dotenv": "^10.0.0",
"express": "^4.17.1",

View File

@ -14,7 +14,7 @@ const constants = {
DECAY_START_TIME: new Date('2021-05-13 17:46:31'), // GMT+0
CONFIG_VERSION: {
DEFAULT: 'DEFAULT',
EXPECTED: 'v5.2022-04-12',
EXPECTED: 'v6.2022-04-21',
CURRENT: '',
},
}
@ -50,6 +50,7 @@ const community = {
COMMUNITY_NAME: process.env.COMMUNITY_NAME || 'Gradido Entwicklung',
COMMUNITY_URL: process.env.COMMUNITY_URL || 'http://localhost/',
COMMUNITY_REGISTER_URL: process.env.COMMUNITY_REGISTER_URL || 'http://localhost/register',
COMMUNITY_REDEEM_URL: process.env.COMMUNITY_REDEEM_URL || 'http://localhost/redeem/{code}',
COMMUNITY_DESCRIPTION:
process.env.COMMUNITY_DESCRIPTION || 'Die lokale Entwicklungsumgebung von Gradido.',
}

View File

@ -2,6 +2,7 @@ import { ObjectType, Field, Int } from 'type-graphql'
import Decimal from 'decimal.js-light'
import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink'
import { User } from './User'
import CONFIG from '@/config'
@ObjectType()
export class TransactionLink {
@ -17,6 +18,7 @@ export class TransactionLink {
this.deletedAt = transactionLink.deletedAt
this.redeemedAt = transactionLink.redeemedAt
this.redeemedBy = redeemedBy
this.link = CONFIG.COMMUNITY_REDEEM_URL.replace(/{code}/g, this.code)
}
@Field(() => Number)
@ -51,6 +53,9 @@ export class TransactionLink {
@Field(() => User, { nullable: true })
redeemedBy: User | null
@Field(() => String)
link: string
}
@ObjectType()

View File

@ -1900,7 +1900,14 @@ create-require@^1.1.0:
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
cross-spawn@^7.0.2, cross-spawn@^7.0.3:
cross-env@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf"
integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==
dependencies:
cross-spawn "^7.0.1"
cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==

View File

@ -10,15 +10,15 @@
"scripts": {
"build": "mkdir -p build/src/config/ && cp src/config/*.txt build/src/config/ && tsc --build",
"clean": "tsc --build --clean",
"up": "TZ=UTC node build/src/index.js up",
"down": "TZ=UTC node build/src/index.js down",
"reset": "TZ=UTC node build/src/index.js reset",
"dev_up": "TZ=UTC ts-node src/index.ts up",
"dev_down": "TZ=UTC ts-node src/index.ts down",
"dev_reset": "TZ=UTC ts-node src/index.ts reset",
"up": "cross-env TZ=UTC node build/src/index.js up",
"down": "cross-env TZ=UTC node build/src/index.js down",
"reset": "cross-env TZ=UTC node build/src/index.js reset",
"dev_up": "cross-env TZ=UTC ts-node src/index.ts up",
"dev_down": "cross-env TZ=UTC ts-node src/index.ts down",
"dev_reset": "cross-env TZ=UTC ts-node src/index.ts reset",
"lint": "eslint --max-warnings=0 --ext .js,.ts .",
"seed:config": "ts-node ./node_modules/typeorm-seeding/dist/cli.js config",
"seed": "TZ=UTC ts-node src/index.ts seed"
"seed": "cross-env TZ=UTC ts-node src/index.ts seed"
},
"devDependencies": {
"@types/faker": "^5.5.9",
@ -37,6 +37,7 @@
"typescript": "^4.3.5"
},
"dependencies": {
"cross-env": "^7.0.3",
"crypto": "^1.0.1",
"decimal.js-light": "^2.5.1",
"dotenv": "^10.0.0",

View File

@ -481,7 +481,14 @@ create-require@^1.1.0:
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
cross-spawn@^7.0.2:
cross-env@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf"
integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==
dependencies:
cross-spawn "^7.0.1"
cross-spawn@^7.0.1, cross-spawn@^7.0.2:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==

View File

@ -24,7 +24,7 @@ COMMUNITY_REGISTER_URL=https://stage1.gradido.net/register
COMMUNITY_DESCRIPTION="Gradido Development Stage1 Test Community"
# backend
BACKEND_CONFIG_VERSION=v5.2022-04-12
BACKEND_CONFIG_VERSION=v6.2022-04-21
JWT_EXPIRES_IN=30m
GDT_API_URL=https://gdt.gradido.net

View File

@ -0,0 +1,135 @@
<mxfile host="65bd71144e">
<diagram id="IM2_X0c97E_FZMH_xTRz" name="Page-1">
<mxGraphModel dx="888" dy="633" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="28" value="Other Community" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#008a00;fontColor=#ffffff;strokeColor=#005700;" vertex="1" parent="1">
<mxGeometry x="360" y="410" width="120" height="90" as="geometry"/>
</mxCell>
<mxCell id="3" value="Appolo Server" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#008a00;fontColor=#ffffff;strokeColor=#005700;" parent="1" vertex="1">
<mxGeometry x="220" y="80" width="280" height="300" as="geometry"/>
</mxCell>
<mxCell id="6" style="edgeStyle=none;html=1;" parent="1" target="5" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="500" y="325" as="sourcePoint"/>
</mxGeometry>
</mxCell>
<mxCell id="25" style="edgeStyle=none;html=1;startArrow=none;startFill=0;" edge="1" parent="1" source="2" target="16">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="27" style="edgeStyle=none;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;startArrow=none;startFill=0;" edge="1" parent="1" source="2" target="26">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="2" value="Node" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#60a917;fontColor=#ffffff;strokeColor=#2D7600;" parent="1" vertex="1">
<mxGeometry x="370" y="300" width="100" height="50" as="geometry"/>
</mxCell>
<mxCell id="5" value="DB" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#1ba1e2;fontColor=#ffffff;strokeColor=#006EAF;" parent="1" vertex="1">
<mxGeometry x="600" y="285" width="60" height="80" as="geometry"/>
</mxCell>
<mxCell id="10" value="Node" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#60a917;fontColor=#ffffff;strokeColor=#2D7600;labelPosition=center;verticalLabelPosition=middle;align=center;verticalAlign=middle;" parent="1" vertex="1">
<mxGeometry x="260" y="575" width="240" height="230" as="geometry"/>
</mxCell>
<mxCell id="14" style="edgeStyle=none;html=1;exitX=0.25;exitY=1;exitDx=0;exitDy=0;entryX=0.25;entryY=0;entryDx=0;entryDy=0;startArrow=none;startFill=0;" parent="1" source="11" target="12" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="11" value="DHT (lookup/annoucne)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#76608a;fontColor=#ffffff;strokeColor=#432D57;" parent="1" vertex="1">
<mxGeometry x="280" y="600" width="200" height="60" as="geometry"/>
</mxCell>
<mxCell id="15" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;startArrow=none;startFill=0;" edge="1" parent="1" source="12" target="13">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="12" value="Direct Connection&lt;br&gt;(exchange endpoints)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#76608a;fontColor=#ffffff;strokeColor=#432D57;" parent="1" vertex="1">
<mxGeometry x="280" y="730" width="200" height="60" as="geometry"/>
</mxCell>
<mxCell id="13" value="DB" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#1ba1e2;fontColor=#ffffff;strokeColor=#006EAF;" parent="1" vertex="1">
<mxGeometry x="600" y="720" width="60" height="80" as="geometry"/>
</mxCell>
<mxCell id="24" value="" style="edgeStyle=none;html=1;startArrow=none;startFill=0;" edge="1" parent="1" source="16" target="23">
<mxGeometry relative="1" as="geometry">
<Array as="points"/>
</mxGeometry>
</mxCell>
<mxCell id="16" value="Verify via GraphQL" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#60a917;fontColor=#ffffff;strokeColor=#2D7600;" vertex="1" parent="1">
<mxGeometry x="240" y="300" width="100" height="50" as="geometry"/>
</mxCell>
<mxCell id="21" value="Other Community" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#008a00;fontColor=#ffffff;strokeColor=#005700;" vertex="1" parent="1">
<mxGeometry x="30" y="71" width="120" height="90" as="geometry"/>
</mxCell>
<mxCell id="22" value="Other Community" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#008a00;fontColor=#ffffff;strokeColor=#005700;" vertex="1" parent="1">
<mxGeometry x="30" y="176" width="120" height="90" as="geometry"/>
</mxCell>
<mxCell id="23" value="Other Community" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#008a00;fontColor=#ffffff;strokeColor=#005700;" vertex="1" parent="1">
<mxGeometry x="30" y="281" width="120" height="90" as="geometry"/>
</mxCell>
<mxCell id="26" value="Node" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#60a917;fontColor=#ffffff;strokeColor=#2D7600;" vertex="1" parent="1">
<mxGeometry x="370" y="430" width="100" height="50" as="geometry"/>
</mxCell>
<mxCell id="29" value="Appolo Server" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#008a00;fontColor=#ffffff;strokeColor=#005700;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="110" y="880" width="540" height="500" as="geometry"/>
</mxCell>
<mxCell id="35" value="" style="edgeStyle=none;html=1;startArrow=classic;startFill=1;" edge="1" parent="1" source="30" target="34">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="690" y="940"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="30" value="Frontend GraphQL Endpoint (unversionated)" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="150" y="910" width="450" height="60" as="geometry"/>
</mxCell>
<mxCell id="31" value="Versionated Endpoints" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="150" y="1010" width="450" height="310" as="geometry"/>
</mxCell>
<mxCell id="34" value="Frontend" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="690" y="910" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="36" value="Other Community" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#008a00;fontColor=#ffffff;strokeColor=#005700;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="700" y="1012" width="140" height="250" as="geometry"/>
</mxCell>
<mxCell id="38" value="&lt;span style=&quot;color: rgba(0 , 0 , 0 , 0) ; font-family: monospace ; font-size: 0px&quot;&gt;%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22Frontend%20GraphQL%20Endpoint%20(unversionated)%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22150%22%20y%3D%221010%22%20width%3D%22450%22%20height%3D%22310%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E&lt;/span&gt;&lt;span style=&quot;color: rgba(0 , 0 , 0 , 0) ; font-family: monospace ; font-size: 0px&quot;&gt;%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22Frontend%20GraphQL%20Endpoint%20(unversionated)%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22150%22%20y%3D%221010%22%20width%3D%22450%22%20height%3D%22310%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E&lt;/span&gt;" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="710" y="1042" width="120" height="30" as="geometry"/>
</mxCell>
<mxCell id="39" value="&lt;span style=&quot;color: rgba(0 , 0 , 0 , 0) ; font-family: monospace ; font-size: 0px&quot;&gt;%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22Frontend%20GraphQL%20Endpoint%20(unversionated)%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22150%22%20y%3D%221010%22%20width%3D%22450%22%20height%3D%22310%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E&lt;/span&gt;&lt;span style=&quot;color: rgba(0 , 0 , 0 , 0) ; font-family: monospace ; font-size: 0px&quot;&gt;%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22Frontend%20GraphQL%20Endpoint%20(unversionated)%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22150%22%20y%3D%221010%22%20width%3D%22450%22%20height%3D%22310%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E&lt;/span&gt;" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="710" y="1082" width="120" height="170" as="geometry"/>
</mxCell>
<mxCell id="48" style="edgeStyle=none;html=1;startArrow=classic;startFill=1;" edge="1" parent="1" source="31" target="39">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="50" value="1.0" style="whiteSpace=wrap;html=1;aspect=fixed;fillColor=#e51400;fontColor=#ffffff;strokeColor=#B20000;" vertex="1" parent="1">
<mxGeometry x="481" y="1050" width="40" height="40" as="geometry"/>
</mxCell>
<mxCell id="51" value="1.1" style="whiteSpace=wrap;html=1;aspect=fixed;fillColor=#e51400;fontColor=#ffffff;strokeColor=#B20000;" vertex="1" parent="1">
<mxGeometry x="481" y="1100" width="40" height="40" as="geometry"/>
</mxCell>
<mxCell id="52" value="2.1" style="whiteSpace=wrap;html=1;aspect=fixed;fillColor=#f0a30a;fontColor=#000000;strokeColor=#BD7000;" vertex="1" parent="1">
<mxGeometry x="480" y="1200" width="40" height="40" as="geometry"/>
</mxCell>
<mxCell id="53" value="2.0" style="whiteSpace=wrap;html=1;aspect=fixed;fillColor=#fa6800;fontColor=#000000;strokeColor=#C73500;" vertex="1" parent="1">
<mxGeometry x="481" y="1150" width="40" height="40" as="geometry"/>
</mxCell>
<mxCell id="54" value="3.0" style="whiteSpace=wrap;html=1;aspect=fixed;fillColor=#e3c800;fontColor=#000000;strokeColor=#B09500;" vertex="1" parent="1">
<mxGeometry x="481" y="1252" width="40" height="40" as="geometry"/>
</mxCell>
<mxCell id="59" value="&lt;span style=&quot;color: rgba(0 , 0 , 0 , 0) ; font-family: monospace ; font-size: 0px&quot;&gt;%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%222.1%22%20style%3D%22whiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22480%22%20y%3D%221200%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E&lt;/span&gt;&lt;span style=&quot;color: rgba(0 , 0 , 0 , 0) ; font-family: monospace ; font-size: 0px&quot;&gt;%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%222.1%22%20style%3D%22whiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22480%22%20y%3D%221200%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E&lt;/span&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#e3c800;fontColor=#000000;strokeColor=#B09500;" vertex="1" parent="1">
<mxGeometry x="170" y="1150" width="300" height="142" as="geometry"/>
</mxCell>
<mxCell id="58" value="&lt;font color=&quot;rgba(0, 0, 0, 0)&quot; face=&quot;monospace&quot;&gt;&lt;span style=&quot;font-size: 0px&quot;&gt;Imp&lt;/span&gt;&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#f0a30a;fontColor=#000000;strokeColor=#BD7000;" vertex="1" parent="1">
<mxGeometry x="220" y="1100" width="250" height="140" as="geometry"/>
</mxCell>
<mxCell id="57" value="&lt;span style=&quot;color: rgba(0 , 0 , 0 , 0) ; font-family: monospace ; font-size: 0px&quot;&gt;%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%222.1%22%20style%3D%22whiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22480%22%20y%3D%221200%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E&lt;/span&gt;&lt;span style=&quot;color: rgba(0 , 0 , 0 , 0) ; font-family: monospace ; font-size: 0px&quot;&gt;%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%222.1%22%20style%3D%22whiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22480%22%20y%3D%221200%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E&lt;/span&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#e51400;fontColor=#ffffff;strokeColor=#B20000;" vertex="1" parent="1">
<mxGeometry x="280" y="1050" width="190" height="90" as="geometry"/>
</mxCell>
<mxCell id="60" value="Implementation 1.x" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#FFFFFF;" vertex="1" parent="1">
<mxGeometry x="317.5" y="1080" width="115" height="30" as="geometry"/>
</mxCell>
<mxCell id="61" value="Implementation&amp;nbsp;2.x&lt;br&gt;(uses parts of the 1.x implementation)" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#000000;" vertex="1" parent="1">
<mxGeometry x="287.5" y="1170" width="115" height="30" as="geometry"/>
</mxCell>
<mxCell id="62" value="Implementation 3.x" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#000000;" vertex="1" parent="1">
<mxGeometry x="280" y="1252" width="115" height="30" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

View File

@ -10,7 +10,7 @@
"analyse-bundle": "yarn build && webpack-bundle-analyzer dist/webpack.stats.json",
"lint": "eslint --max-warnings=0 --ext .js,.vue,.json .",
"stylelint": "stylelint --max-warnings=0 '**/*.{scss,vue}'",
"test": "TZ=UTC jest --coverage",
"test": "cross-env TZ=UTC jest --coverage",
"locales": "scripts/sort.sh"
},
"dependencies": {
@ -72,6 +72,7 @@
"babel-eslint": "^10.1.0",
"babel-plugin-component": "^1.1.0",
"babel-plugin-transform-require-context": "^0.1.1",
"cross-env": "^7.0.3",
"dotenv-webpack": "^7.0.3",
"postcss": "^8.4.8",
"postcss-html": "^1.3.0",

View File

@ -1,11 +1,14 @@
<template>
<div class="clipboard-copy">
<b-input-group size="lg" class="mb-3" prepend="Link">
<b-form-input :value="text" type="text" readonly></b-form-input>
<b-form-input :value="link" type="text" readonly></b-form-input>
<b-input-group-append>
<b-button size="sm" text="Button" variant="success" @click="CopyLink">
<b-button size="sm" text="Button" variant="primary" @click="CopyLink">
{{ $t('gdd_per_link.copy') }}
</b-button>
<b-button variant="primary" class="text-light" @click="$emit('show-qr-code-button')">
<b-img src="img/svg/qr-code.svg" width="19" class="svg"></b-img>
</b-button>
</b-input-group-append>
</b-input-group>
</div>
@ -14,12 +17,12 @@
export default {
name: 'ClipboardCopy',
props: {
text: { type: String, required: true },
link: { type: String, required: true },
},
methods: {
CopyLink() {
navigator.clipboard
.writeText(this.url)
.writeText(this.link)
.then(() => {
this.toastSuccess(this.$t('gdd_per_link.link-copied'))
})
@ -30,3 +33,8 @@ export default {
},
}
</script>
<style>
.svg {
filter: brightness(0) invert(1);
}
</style>

View File

@ -17,6 +17,7 @@ const propsData = {
{
amount: '5',
code: 'ce28664b5308c17f931c0367',
link: 'http://localhost/redeem/ce28664b5308c17f931c0367',
createdAt: '2022-03-16T14:22:40.000Z',
holdAvailableAmount: '5.13109484759482747111',
id: 87,
@ -27,6 +28,7 @@ const propsData = {
{
amount: '6',
code: 'ce28664b5308c17f931c0367',
link: 'http://localhost/redeem/ce28664b5308c17f931c0367',
createdAt: '2022-03-16T14:22:40.000Z',
holdAvailableAmount: '5.13109484759482747111',
id: 86,

View File

@ -3,13 +3,12 @@
<b-col>
<b-card class="p-0 gradido-custom-background">
<div class="h3 mb-4">{{ $t('gdd_per_link.created') }}</div>
<clipboard-copy :text="link" />
<clipboard-copy :link="link" @show-qr-code-button="showQrCodeButton" />
<div class="text-center">
<figure-qr-code :text="link" />
<figure-qr-code v-if="showQrcode" :link="link" />
<b-button variant="success" @click="$emit('on-reset')" class="mt-4">
<b-button variant="secondary" @click="$emit('on-reset')" class="mt-4">
{{ $t('form.close') }}
</b-button>
</div>
@ -28,14 +27,19 @@ export default {
FigureQrCode,
},
props: {
code: {
link: {
type: String,
required: true,
},
},
computed: {
link() {
return `${window.location.origin}/redeem/${this.code}`
data() {
return {
showQrcode: false,
}
},
methods: {
showQrCodeButton() {
this.showQrcode = !this.showQrcode
},
},
}

View File

@ -22,7 +22,9 @@
<div v-else>{{ errorResult }}</div>
</div>
<p class="text-center mt-3">
<b-button variant="success" @click="$emit('on-reset')">{{ $t('form.close') }}</b-button>
<b-button variant="secondary" @click="$emit('on-reset')">
{{ $t('form.close') }}
</b-button>
</p>
</b-card>
</b-col>

View File

@ -9,7 +9,7 @@
{{ $t('form.send_transaction_success') }}
</div>
<p class="text-center mt-3">
<b-button variant="success" @click="$emit('on-reset')">{{ $t('form.close') }}</b-button>
<b-button variant="primary" @click="$emit('on-reset')">{{ $t('form.close') }}</b-button>
</p>
</b-card>
</b-col>

View File

@ -4,7 +4,7 @@ import FigureQrCode from './FigureQrCode'
const localVue = global.localVue
const propsData = {
text: '',
link: '',
}
describe('FigureQrCode', () => {

View File

@ -14,14 +14,14 @@ export default {
QRCanvas,
},
props: {
text: { type: String, required: true },
link: { type: String, required: true },
},
data() {
return {
options: {
cellSize: 8,
correctLevel: 'H',
data: this.text,
data: this.link,
},
}
},

View File

@ -22,7 +22,7 @@ const mocks = {
const propsData = {
amount: '75',
code: 'c00000000c000000c0000',
link: 'http://localhost/redeem/c00000000c000000c0000',
holdAvailableAmount: '5.13109484759482747111',
id: 12,
memo: 'Katzenauge, Eulenschrei, was verschwunden komm herbei!',
@ -44,115 +44,140 @@ describe('TransactionLink', () => {
expect(wrapper.find('div.transaction-link').exists()).toBeTruthy()
})
describe('Copy link to Clipboard', () => {
const navigatorClipboard = navigator.clipboard
beforeAll(() => {
delete navigator.clipboard
navigator.clipboard = { writeText: navigatorClipboardMock }
})
afterAll(() => {
navigator.clipboard = navigatorClipboard
describe('Link validUntil Date is not valid', () => {
it('has no copy link button', () => {
expect(wrapper.find('.test-copy-link').exists()).toBe(false)
})
describe('copy with success', () => {
beforeEach(async () => {
navigatorClipboardMock.mockResolvedValue()
await wrapper.find('.test-copy-link').trigger('click')
})
it('should call clipboard.writeText', () => {
expect(navigator.clipboard.writeText).toHaveBeenCalledWith(
'http://localhost/redeem/c00000000c000000c0000',
)
})
it('toasts success message', () => {
expect(toastSuccessSpy).toBeCalledWith('gdd_per_link.link-copied')
})
it('has no Qr-Code Button ', () => {
expect(wrapper.find('.test-qr-code').exists()).toBe(false)
})
it('has delete link button ', () => {
expect(wrapper.find('.test-delete-link').exists()).toBe(true)
})
})
describe('qr code modal', () => {
let spy
beforeEach(() => {
describe('Link validUntil Date is valid ', () => {
beforeEach(async () => {
const now = new Date()
jest.clearAllMocks()
await wrapper.setProps({
validUntil: `${new Date(now.getFullYear(), now.getMonth(), now.getDate() + 2)}`,
})
})
describe('with success', () => {
describe('Copy link to Clipboard', () => {
const navigatorClipboard = navigator.clipboard
beforeAll(() => {
delete navigator.clipboard
navigator.clipboard = { writeText: navigatorClipboardMock }
})
afterAll(() => {
navigator.clipboard = navigatorClipboard
})
describe('copy with success', () => {
beforeEach(async () => {
navigatorClipboardMock.mockResolvedValue()
await wrapper.find('.test-copy-link .dropdown-item').trigger('click')
})
it('should call clipboard.writeText', () => {
expect(navigator.clipboard.writeText).toHaveBeenCalledWith(
'http://localhost/redeem/c00000000c000000c0000',
)
})
it('toasts success message', () => {
expect(toastSuccessSpy).toBeCalledWith('gdd_per_link.link-copied')
})
})
})
describe('qr code modal', () => {
let spy
beforeEach(async () => {
spy = jest.spyOn(wrapper.vm.$bvModal, 'show')
// spy.mockImplementation(() => Promise.resolve('some value'))
// mockAPIcall.mockResolvedValue()
await wrapper.find('.test-qr-code').trigger('click')
jest.clearAllMocks()
})
it('qr-code Modal if show', () => {
expect(spy).toBeCalled()
describe('with success', () => {
beforeEach(async () => {
spy = jest.spyOn(wrapper.vm.$bvModal, 'show')
// spy.mockImplementation(() => Promise.resolve('some value'))
// mockAPIcall.mockResolvedValue()
await wrapper.find('.test-qr-code .dropdown-item').trigger('click')
})
it('opens the qr-code Modal', () => {
expect(spy).toBeCalled()
})
})
})
})
describe('delete link', () => {
let spy
describe('delete link', () => {
let spy
beforeEach(() => {
jest.clearAllMocks()
})
describe('with success', () => {
beforeEach(async () => {
spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm')
spy.mockImplementation(() => Promise.resolve('some value'))
mockAPIcall.mockResolvedValue()
await wrapper.find('.test-delete-link').trigger('click')
jest.clearAllMocks()
})
it('test Modal if confirm true', () => {
expect(spy).toBeCalled()
describe('with success', () => {
beforeEach(async () => {
spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm')
spy.mockImplementation(() => Promise.resolve('some value'))
mockAPIcall.mockResolvedValue()
await wrapper.find('.test-delete-link .dropdown-item').trigger('click')
})
it('opens the modal ', () => {
expect(spy).toBeCalled()
})
it('calls the API', () => {
expect(mockAPIcall).toBeCalledWith(
expect.objectContaining({
mutation: deleteTransactionLink,
variables: {
id: 12,
},
}),
)
})
it('toasts a success message', () => {
expect(toastSuccessSpy).toBeCalledWith('gdd_per_link.deleted')
})
it('emits reset transaction link list', () => {
expect(wrapper.emitted('reset-transaction-link-list')).toBeTruthy()
})
})
it('calls the API', () => {
expect(mockAPIcall).toBeCalledWith(
expect.objectContaining({
mutation: deleteTransactionLink,
variables: {
id: 12,
},
}),
)
describe('with error', () => {
beforeEach(async () => {
spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm')
spy.mockImplementation(() => Promise.resolve('some value'))
mockAPIcall.mockRejectedValue({ message: 'Something went wrong :(' })
await wrapper.find('.test-delete-link .dropdown-item').trigger('click')
})
it('toasts an error message', () => {
expect(toastErrorSpy).toBeCalledWith('Something went wrong :(')
})
})
it('toasts a success message', () => {
expect(toastSuccessSpy).toBeCalledWith('gdd_per_link.deleted')
})
describe('cancel delete', () => {
beforeEach(async () => {
spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm')
spy.mockImplementation(() => Promise.resolve(false))
mockAPIcall.mockResolvedValue()
await wrapper.find('.test-delete-link .dropdown-item').trigger('click')
})
it('emits reset transaction link list', () => {
expect(wrapper.emitted('reset-transaction-link-list')).toBeTruthy()
})
})
describe('with error', () => {
beforeEach(async () => {
spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm')
spy.mockImplementation(() => Promise.resolve('some value'))
mockAPIcall.mockRejectedValue({ message: 'Something went wrong :(' })
await wrapper.find('.test-delete-link').trigger('click')
})
it('toasts an error message', () => {
expect(toastErrorSpy).toBeCalledWith('Something went wrong :(')
})
})
describe('cancel delete', () => {
beforeEach(async () => {
spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm')
spy.mockImplementation(() => Promise.resolve(false))
mockAPIcall.mockResolvedValue()
await wrapper.find('.test-delete-link').trigger('click')
})
it('does not call the API', () => {
expect(mockAPIcall).not.toBeCalled()
it('does not call the API', () => {
expect(mockAPIcall).not.toBeCalled()
})
})
})
})

View File

@ -1,55 +1,54 @@
<template>
<div class="transaction-link gradido-custom-background">
<b-row class="mb-2 pt-2 pb-2">
<b-col lg="2">
<b-row :class="validLink ? '' : 'bg-muted text-light'" class="mb-2 pt-2 pb-2">
<b-col cols="1">
<type-icon color="text-danger" icon="link45deg" class="pt-4 pl-2" />
</b-col>
<b-col lg="9" md="9">
<b-col cols="11">
<b-row>
<b-col lg="11" md="10">
<b-col>
<amount-and-name-row :amount="amount" :text="$t('form.amount')" />
<memo-row :memo="memo" />
<date-row :date="validUntil" :diffNow="true" />
<date-row :date="validUntil" :diffNow="true" :validLink="validLink" />
<decay-row :decay="decay" />
</b-col>
<b-col lg="1" md="2" class="text-center text-lg-left qr-button">
<b-button
@click="$bvModal.show('modalPopover-' + id)"
class="p-2 test-qr-code"
size="sm"
>
<b-img src="img/svg/qr-code.svg" width="60" class="filter"></b-img>
</b-button>
<b-col cols="12" lg="1" md="1" class="text-center text-md-right pr-5 pr-lg-4">
<b-dropdown no-caret right aria-expanded="false" size="sm">
<template #button-content>
<b-icon icon="three-dots-vertical"></b-icon>
</template>
<b-dropdown-item v-if="validLink" class="test-copy-link" @click="copy">
<b-icon icon="clipboard"></b-icon>
{{ $t('gdd_per_link.copy') }}
</b-dropdown-item>
<b-dropdown-item
v-if="validLink"
@click="$bvModal.show('modalPopover-' + id)"
class="pt-3 pb-3 test-qr-code"
>
<b-img src="img/svg/qr-code.svg" width="18" class="filter"></b-img>
{{ $t('qrCode') }}
</b-dropdown-item>
<b-dropdown-item class="test-delete-link" @click="deleteLink()">
<b-icon icon="trash"></b-icon>
{{ $t('delete') }}
</b-dropdown-item>
</b-dropdown>
</b-col>
</b-row>
</b-col>
<b-col lg="1" md="1" class="text-center text-lg-right">
<b-button
class="p-2 test-copy-link"
size="lg"
variant="outline-primary"
@click="copy"
:title="$t('gdd_per_link.copy')"
>
<b-icon icon="clipboard"></b-icon>
</b-button>
<br />
<b-button
class="p-2 mt-3 test-delete-link"
size="sm"
@click="deleteLink()"
:title="$t('delete')"
>
<b-icon icon="trash"></b-icon>
</b-button>
</b-col>
</b-row>
<b-modal :id="'modalPopover-' + id" title="QR-Code" ok-only hide-header-close>
<div class="text-center">
<figure-qr-code :text="link" />
<p>{{ link }}</p>
</div>
<b-modal :id="'modalPopover-' + id" ok-only hide-header-close>
<b-card header-tag="header" footer-tag="footer">
<template #header>
<h6 class="mb-0">{{ $t('qrCode') }}</h6>
</template>
<b-card-text><figure-qr-code class="text-center" :link="link" /></b-card-text>
<template #footer>
<em>{{ link }}</em>
</template>
</b-card>
</b-modal>
</div>
</template>
@ -74,7 +73,7 @@ export default {
},
props: {
amount: { type: String, required: true },
code: { type: String, required: true },
link: { type: String, required: true },
holdAvailableAmount: { type: String, required: true },
id: { type: Number, required: true },
memo: { type: String, required: true },
@ -115,8 +114,8 @@ export default {
decay() {
return `${this.amount - this.holdAvailableAmount}`
},
link() {
return `${window.location.origin}/redeem/${this.code}`
validLink() {
return new Date(this.validUntil) > new Date()
},
},
}

View File

@ -3,7 +3,7 @@
<b-row>
<b-col cols="5">
<div class="text-right">
{{ diffNow ? $t('gdd_per_link.valid_until') : $t('form.date') }}
{{ text }}
</div>
</b-col>
<b-col cols="7">
@ -27,6 +27,20 @@ export default {
required: false,
default: false,
},
validLink: {
type: Boolean,
required: false,
default: false,
},
},
computed: {
text() {
if (this.diffNow)
return this.validLink
? this.$t('gdd_per_link.validUntil')
: this.$t('gdd_per_link.expiredOn')
return this.$t('form.date')
},
},
}
</script>

View File

@ -44,7 +44,7 @@ describe('TransactionLinkSummary', () => {
listTransactionLinks: [
{
amount: '75',
code: 'ce28664b5308c17f931c0367',
link: 'http://localhost/redeem/ce28664b5308c17f931c0367',
createdAt: '2022-03-16T14:22:40.000Z',
holdAvailableAmount: '5.13109484759482747111',
id: 86,
@ -55,7 +55,7 @@ describe('TransactionLinkSummary', () => {
},
{
amount: '85',
code: 'ce28664b5308c17f931c0367',
link: 'http://localhost/redeem/ce28664b5308c17f931c0367',
createdAt: '2022-03-16T14:22:40.000Z',
holdAvailableAmount: '5.13109484759482747111',
id: 107,
@ -65,7 +65,7 @@ describe('TransactionLinkSummary', () => {
},
{
amount: '95',
code: 'ce28664b5308c17f931c0367',
link: 'http://localhost/redeem/ce28664b5308c17f931c0367',
createdAt: '2022-03-16T14:22:40.000Z',
holdAvailableAmount: '5.13109484759482747111',
id: 92,
@ -76,7 +76,7 @@ describe('TransactionLinkSummary', () => {
},
{
amount: '150',
code: 'ce28664b5308c17f931c0367',
link: 'http://localhost/redeem/ce28664b5308c17f931c0367',
createdAt: '2022-03-16T14:22:40.000Z',
holdAvailableAmount: '5.13109484759482747111',
id: 16,
@ -132,6 +132,27 @@ describe('TransactionLinkSummary', () => {
it('has no component CollapseLinksList', () => {
expect(wrapper.findComponent({ name: 'CollapseLinksList' }).isVisible()).toBe(false)
})
describe('reopen transaction link details', () => {
beforeEach(() => {
jest.clearAllMocks()
wrapper.find('div.transaction-link-details').trigger('click')
})
it('calls the API to get the list transaction links', () => {
expect(apolloQueryMock).toBeCalledWith({
query: listTransactionLinks,
variables: {
currentPage: 1,
},
fetchPolicy: 'network-only',
})
})
it('has four transactionLinks', () => {
expect(wrapper.vm.transactionLinks).toHaveLength(4)
})
})
})
describe('load more transaction links', () => {
@ -142,7 +163,7 @@ describe('TransactionLinkSummary', () => {
listTransactionLinks: [
{
amount: '76',
code: 'ce28664b5308c17f931c0367',
link: 'http://localhost/redeem/ce28664b5308c17f931c0367',
createdAt: '2022-03-16T14:22:40.000Z',
holdAvailableAmount: '5.13109484759482747111',
id: 87,
@ -153,7 +174,7 @@ describe('TransactionLinkSummary', () => {
},
{
amount: '86',
code: 'ce28664b5308c17f931c0367',
link: 'http://localhost/redeem/ce28664b5308c17f931c0367',
createdAt: '2022-03-16T14:22:40.000Z',
holdAvailableAmount: '5.13109484759482747111',
id: 108,
@ -164,7 +185,7 @@ describe('TransactionLinkSummary', () => {
},
{
amount: '96',
code: 'ce28664b5308c17f931c0367',
link: 'http://localhost/redeem/ce28664b5308c17f931c0367',
createdAt: '2022-03-16T14:22:40.000Z',
holdAvailableAmount: '5.13109484759482747111',
id: 93,
@ -175,7 +196,7 @@ describe('TransactionLinkSummary', () => {
},
{
amount: '150',
code: 'ce28664b5308c17f931c0367',
link: 'http://localhost/redeem/ce28664b5308c17f931c0367',
createdAt: '2022-03-16T14:22:40.000Z',
holdAvailableAmount: '5.13109484759482747111',
id: 17,

View File

@ -83,6 +83,7 @@ export default {
if (this.visible) {
this.visible = false
} else {
this.transactionLinks = []
this.updateListTransactionLinks()
this.visible = true
}

View File

@ -75,7 +75,7 @@ export const sendCoins = gql`
export const createTransactionLink = gql`
mutation($amount: Decimal!, $memo: String!) {
createTransactionLink(amount: $amount, memo: $memo) {
code
link
}
}
`

View File

@ -139,7 +139,7 @@ export const listTransactionLinks = gql`
amount
holdAvailableAmount
memo
code
link
createdAt
validUntil
redeemedAt

View File

@ -102,6 +102,7 @@
"decay-14-day": "Vergänglichkeit für 14 Tage",
"delete-the-link": "Den Link löschen?",
"deleted": "Der Link wurde gelöscht!",
"expiredOn": "Abgelaufen am",
"has-account": "Du besitzt bereits ein Gradido Konto?",
"header": "Gradidos versenden per Link",
"isFree": "Gradido ist weltweit kostenfrei.",
@ -121,7 +122,7 @@
"redeemed-title": "eingelöst",
"to-login": "Log dich ein",
"to-register": "Registriere ein neues Konto.",
"valid_until": "Gültig bis"
"validUntil": "Gültig bis"
},
"gdt": {
"calculation": "Berechnung der Gradido Transform",
@ -164,6 +165,7 @@
"infoText": "Wenn dir dein Empfehlungsgeber seine Publisher-Id gegeben hat, trage sie hier ein, sonst lass das Feld bitte unverändert!",
"publisherId": "Publisher-Id:"
},
"qrCode": "QR Code",
"send_gdd": "GDD versenden",
"send_per_link": "GDD versenden per Link",
"settings": {

View File

@ -102,6 +102,7 @@
"decay-14-day": "Decay for 14 days",
"delete-the-link": "Delete the link?",
"deleted": "The link was deleted!",
"expiredOn": "Expired on",
"has-account": "You already have a Gradido account?",
"header": "Send Gradidos via link",
"isFree": "Gradido is free of charge worldwide.",
@ -121,7 +122,7 @@
"redeemed-title": "redeemed",
"to-login": "Log in",
"to-register": "Register a new account.",
"valid_until": "Valid until"
"validUntil": "Valid until"
},
"gdt": {
"calculation": "Calculation of Gradido Transform",
@ -164,6 +165,7 @@
"infoText": "If your referrer has given you his publisher id, enter it here, otherwise leave the field unchanged!",
"publisherId": "PublisherID:"
},
"qrCode": "QR Code",
"send_gdd": "GDD send",
"send_per_link": "GDD send via link",
"settings": {

View File

@ -162,7 +162,11 @@ describe('Send', () => {
describe('transaction form link', () => {
beforeEach(async () => {
apolloMutationMock.mockResolvedValue({
data: { createTransactionLink: { code: '0123456789' } },
data: {
createTransactionLink: {
link: 'http://localhost/redeem/0123456789',
},
},
})
const transactionForm = wrapper.findComponent({ name: 'TransactionForm' })
await transactionForm.findAll('input[type="radio"]').at(1).setChecked()
@ -249,7 +253,7 @@ describe('Send', () => {
describe('close button click', () => {
beforeEach(async () => {
await wrapper.findAll('button').at(1).trigger('click')
await wrapper.findAll('button').at(2).trigger('click')
})
it('Shows the TransactionForm', () => {

View File

@ -41,7 +41,7 @@
></transaction-result-send-error>
</template>
<template #transactionResultLink>
<transaction-result-link :code="code" @on-reset="onReset"></transaction-result-link>
<transaction-result-link :link="link" @on-reset="onReset"></transaction-result-link>
</template>
</gdd-send>
<hr />
@ -87,7 +87,7 @@ export default {
errorResult: '',
currentTransactionStep: TRANSACTION_STEPS.transactionForm,
loading: false,
code: null,
link: null,
}
},
props: {
@ -144,7 +144,7 @@ export default {
})
.then((result) => {
this.$emit('set-tunneled-email', null)
this.code = result.data.createTransactionLink.code
this.link = result.data.createTransactionLink.link
this.transactionData = { ...EMPTY_TRANSACTION_DATA }
this.currentTransactionStep = TRANSACTION_STEPS.transactionResultLink
this.updateTransactions({})

View File

@ -5276,6 +5276,13 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
cross-env@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf"
integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==
dependencies:
cross-spawn "^7.0.1"
cross-spawn@^5.0.1, cross-spawn@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
@ -5296,7 +5303,7 @@ cross-spawn@^6.0.0:
shebang-command "^1.2.0"
which "^1.2.9"
cross-spawn@^7.0.0, cross-spawn@^7.0.2:
cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==