Merge pull request #2098 from gradido/2077-copy-text-after-transaction-link-creation

Enable copying the link, username, amount, and memo text after transaction link creation
This commit is contained in:
mahula 2022-07-27 15:20:20 +02:00 committed by GitHub
commit d134b7efe1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 94 additions and 17 deletions

View File

@ -3,8 +3,11 @@
<b-input-group v-if="canCopyLink" size="lg" class="mb-3" prepend="Link"> <b-input-group v-if="canCopyLink" size="lg" class="mb-3" prepend="Link">
<b-form-input :value="link" type="text" readonly></b-form-input> <b-form-input :value="link" type="text" readonly></b-form-input>
<b-input-group-append> <b-input-group-append>
<b-button size="sm" text="Button" variant="primary" @click="copyLinkWithText">
{{ $t('gdd_per_link.copy-link-with-text') }}
</b-button>
<b-button size="sm" text="Button" variant="primary" @click="CopyLink"> <b-button size="sm" text="Button" variant="primary" @click="CopyLink">
{{ $t('gdd_per_link.copy') }} {{ $t('gdd_per_link.copy-link') }}
</b-button> </b-button>
<b-button variant="primary" class="text-light" @click="$emit('show-qr-code-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-img src="img/svg/qr-code.svg" width="19" class="svg"></b-img>
@ -22,6 +25,8 @@ export default {
name: 'ClipboardCopy', name: 'ClipboardCopy',
props: { props: {
link: { type: String, required: true }, link: { type: String, required: true },
amount: { type: Number, required: true },
memo: { type: String, required: true },
}, },
data() { data() {
return { return {
@ -40,6 +45,21 @@ export default {
this.toastError(this.$t('gdd_per_link.not-copied')) this.toastError(this.$t('gdd_per_link.not-copied'))
}) })
}, },
copyLinkWithText() {
navigator.clipboard
.writeText(
`${this.link}
${this.$store.state.firstName} ${this.$t('transaction-link.send_you')} ${this.amount} Gradido.
"${this.memo}"`,
)
.then(() => {
this.toastSuccess(this.$t('gdd_per_link.link-and-text-copied'))
})
.catch(() => {
this.canCopyLink = false
this.toastError(this.$t('gdd_per_link.not-copied'))
})
},
}, },
} }
</script> </script>

View File

@ -3,7 +3,12 @@
<b-col> <b-col>
<b-card class="p-0 gradido-custom-background"> <b-card class="p-0 gradido-custom-background">
<div class="h3 mb-4">{{ $t('gdd_per_link.created') }}</div> <div class="h3 mb-4">{{ $t('gdd_per_link.created') }}</div>
<clipboard-copy :link="link" @show-qr-code-button="showQrCodeButton" /> <clipboard-copy
:link="link"
:amount="amount"
:memo="memo"
@show-qr-code-button="showQrCodeButton"
></clipboard-copy>
<div class="text-center"> <div class="text-center">
<figure-qr-code v-if="showQrcode" :link="link" /> <figure-qr-code v-if="showQrcode" :link="link" />
@ -27,10 +32,9 @@ export default {
FigureQrCode, FigureQrCode,
}, },
props: { props: {
link: { link: { type: String, required: true },
type: String, amount: { type: Number, required: true },
required: true, memo: { type: String, required: true },
},
}, },
data() { data() {
return { return {

View File

@ -20,7 +20,7 @@
<b-dropdown-item v-if="validLink" class="test-copy-link" @click="copy"> <b-dropdown-item v-if="validLink" class="test-copy-link" @click="copy">
<b-icon icon="clipboard"></b-icon> <b-icon icon="clipboard"></b-icon>
{{ $t('gdd_per_link.copy') }} {{ $t('gdd_per_link.copy-link') }}
</b-dropdown-item> </b-dropdown-item>
<b-dropdown-item <b-dropdown-item
v-if="validLink" v-if="validLink"
@ -28,7 +28,7 @@
@click="copyLinkWithText()" @click="copyLinkWithText()"
> >
<b-icon icon="clipboard-plus"></b-icon> <b-icon icon="clipboard-plus"></b-icon>
{{ $t('gdd_per_link.copy-with-text') }} {{ $t('gdd_per_link.copy-link-with-text') }}
</b-dropdown-item> </b-dropdown-item>
<b-dropdown-item <b-dropdown-item
v-if="validLink" v-if="validLink"

View File

@ -151,8 +151,8 @@
"GDD": "GDD", "GDD": "GDD",
"gdd_per_link": { "gdd_per_link": {
"choose-amount": "Wähle einen Betrag aus, welchen du per Link versenden möchtest. Du kannst auch noch eine Nachricht eintragen. Beim Klick „Jetzt generieren“ wird ein Link erstellt, den du versenden kannst.", "choose-amount": "Wähle einen Betrag aus, welchen du per Link versenden möchtest. Du kannst auch noch eine Nachricht eintragen. Beim Klick „Jetzt generieren“ wird ein Link erstellt, den du versenden kannst.",
"copy": "kopieren", "copy-link": "Link kopieren",
"copy-with-text": "Link und Text kopieren", "copy-link-with-text": "Link und Text kopieren",
"created": "Der Link wurde erstellt!", "created": "Der Link wurde erstellt!",
"credit-your-gradido": "Damit die Gradido gutgeschrieben werden können, klicke auf den Link!", "credit-your-gradido": "Damit die Gradido gutgeschrieben werden können, klicke auf den Link!",
"decay-14-day": "Vergänglichkeit für 14 Tage", "decay-14-day": "Vergänglichkeit für 14 Tage",

View File

@ -151,8 +151,8 @@
"GDD": "GDD", "GDD": "GDD",
"gdd_per_link": { "gdd_per_link": {
"choose-amount": "Select an amount that you would like to send via link. You can also enter a message. Click 'Generate now' to create a link that you can share.", "choose-amount": "Select an amount that you would like to send via link. You can also enter a message. Click 'Generate now' to create a link that you can share.",
"copy": "copy", "copy-link": "Copy link",
"copy-with-text": "Copy link and text", "copy-link-with-text": "Copy link and text",
"created": "Link was created!", "created": "Link was created!",
"credit-your-gradido": "For the Gradido to be credited, click on the link!", "credit-your-gradido": "For the Gradido to be credited, click on the link!",
"decay-14-day": "Decay for 14 days", "decay-14-day": "Decay for 14 days",

View File

@ -28,6 +28,7 @@ describe('Send', () => {
$store: { $store: {
state: { state: {
email: 'sender@example.org', email: 'sender@example.org',
firstName: 'Testy',
}, },
}, },
$apollo: { $apollo: {
@ -228,18 +229,63 @@ describe('Send', () => {
navigator.clipboard = navigatorClipboard navigator.clipboard = navigatorClipboard
}) })
describe('copy with success', () => { describe('copy link with success', () => {
beforeEach(async () => { beforeEach(async () => {
navigatorClipboardMock.mockResolvedValue() navigatorClipboardMock.mockResolvedValue()
await wrapper.findAll('button').at(0).trigger('click') await wrapper.findAll('button').at(1).trigger('click')
}) })
it('should call clipboard.writeText', () => {
expect(navigator.clipboard.writeText).toHaveBeenCalledWith(
'http://localhost/redeem/0123456789',
)
})
it('toasts success message', () => { it('toasts success message', () => {
expect(toastSuccessSpy).toBeCalledWith('gdd_per_link.link-copied') expect(toastSuccessSpy).toBeCalledWith('gdd_per_link.link-copied')
}) })
}) })
describe('copy with error', () => { describe('copy link with error', () => {
beforeEach(async () => {
navigatorClipboardMock.mockRejectedValue()
await wrapper.findAll('button').at(1).trigger('click')
})
it('toasts error message', () => {
expect(toastErrorSpy).toBeCalledWith('gdd_per_link.not-copied')
})
})
})
describe('copy link and text with success', () => {
const navigatorClipboard = navigator.clipboard
beforeAll(() => {
delete navigator.clipboard
navigator.clipboard = { writeText: navigatorClipboardMock }
})
afterAll(() => {
navigator.clipboard = navigatorClipboard
})
describe('copy link and text with success', () => {
beforeEach(async () => {
navigatorClipboardMock.mockResolvedValue()
await wrapper.findAll('button').at(0).trigger('click')
})
it('should call clipboard.writeText', () => {
expect(navigator.clipboard.writeText).toHaveBeenCalledWith(
'http://localhost/redeem/0123456789\n' +
'Testy transaction-link.send_you 56.78 Gradido.\n' +
'"Make the best of the link!"',
)
})
it('toasts success message', () => {
expect(toastSuccessSpy).toBeCalledWith('gdd_per_link.link-and-text-copied')
})
})
describe('copy link and text with error', () => {
beforeEach(async () => { beforeEach(async () => {
navigatorClipboardMock.mockRejectedValue() navigatorClipboardMock.mockRejectedValue()
await wrapper.findAll('button').at(0).trigger('click') await wrapper.findAll('button').at(0).trigger('click')
@ -253,7 +299,7 @@ describe('Send', () => {
describe('close button click', () => { describe('close button click', () => {
beforeEach(async () => { beforeEach(async () => {
await wrapper.findAll('button').at(2).trigger('click') await wrapper.findAll('button').at(3).trigger('click')
}) })
it('Shows the TransactionForm', () => { it('Shows the TransactionForm', () => {

View File

@ -41,7 +41,12 @@
></transaction-result-send-error> ></transaction-result-send-error>
</template> </template>
<template #transactionResultLink> <template #transactionResultLink>
<transaction-result-link :link="link" @on-reset="onReset"></transaction-result-link> <transaction-result-link
:link="link"
:amount="amount"
:memo="memo"
@on-reset="onReset"
></transaction-result-link>
</template> </template>
</gdd-send> </gdd-send>
<hr /> <hr />
@ -145,6 +150,8 @@ export default {
.then((result) => { .then((result) => {
this.$emit('set-tunneled-email', null) this.$emit('set-tunneled-email', null)
this.link = result.data.createTransactionLink.link this.link = result.data.createTransactionLink.link
this.amount = this.transactionData.amount
this.memo = this.transactionData.memo
this.transactionData = { ...EMPTY_TRANSACTION_DATA } this.transactionData = { ...EMPTY_TRANSACTION_DATA }
this.currentTransactionStep = TRANSACTION_STEPS.transactionResultLink this.currentTransactionStep = TRANSACTION_STEPS.transactionResultLink
this.updateTransactions({}) this.updateTransactions({})