@@ -27,10 +33,10 @@ export default {
FigureQrCode,
},
props: {
- link: {
- type: String,
- required: true,
- },
+ link: { type: String, required: true },
+ amount: { type: String, required: true },
+ memo: { type: String, required: true },
+ validUntil: { type: String, required: true },
},
data() {
return {
diff --git a/frontend/src/components/GddTransactionList.vue b/frontend/src/components/GddTransactionList.vue
index 5becfa39e..a74be5187 100644
--- a/frontend/src/components/GddTransactionList.vue
+++ b/frontend/src/components/GddTransactionList.vue
@@ -69,6 +69,7 @@
:per-page="pageSize"
:total-rows="transactionCount"
align="center"
+ :hide-ellipsis="true"
>
diff --git a/frontend/src/components/GdtTransactionList.vue b/frontend/src/components/GdtTransactionList.vue
index 4934f9fce..f915cd881 100644
--- a/frontend/src/components/GdtTransactionList.vue
+++ b/frontend/src/components/GdtTransactionList.vue
@@ -36,6 +36,7 @@
:per-page="pageSize"
:total-rows="transactionGdtCount"
align="center"
+ :hide-ellipsis="true"
>
diff --git a/frontend/src/components/Menu/Navbar.spec.js b/frontend/src/components/Menu/Navbar.spec.js
index ebf9abba0..3f12682c0 100644
--- a/frontend/src/components/Menu/Navbar.spec.js
+++ b/frontend/src/components/Menu/Navbar.spec.js
@@ -17,7 +17,7 @@ const mocks = {
$t: jest.fn((t) => t),
$store: {
state: {
- hasElopage: false,
+ hasElopage: true,
isAdmin: true,
},
},
@@ -39,15 +39,17 @@ describe('Navbar', () => {
expect(wrapper.find('div.component-navbar').exists()).toBeTruthy()
})
- describe('navigation Navbar', () => {
+ describe('navigation Navbar (general elements)', () => {
it('has .navbar-brand in the navbar', () => {
expect(wrapper.find('.navbar-brand').exists()).toBeTruthy()
})
+
it('has b-navbar-toggle in the navbar', () => {
expect(wrapper.find('.navbar-toggler').exists()).toBeTruthy()
})
+
it('has ten b-nav-item in the navbar', () => {
- expect(wrapper.findAll('.nav-item')).toHaveLength(10)
+ expect(wrapper.findAll('.nav-item')).toHaveLength(11)
})
it('has first nav-item "amount GDD" in navbar', () => {
@@ -57,31 +59,57 @@ describe('Navbar', () => {
it('has first nav-item "navigation.overview" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(3).text()).toEqual('navigation.overview')
})
+
it('has first nav-item "navigation.send" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(4).text()).toEqual('navigation.send')
})
+
it('has first nav-item "navigation.transactions" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(5).text()).toEqual('navigation.transactions')
})
- it('has first nav-item "navigation.profile" in navbar', () => {
- expect(wrapper.findAll('.nav-item').at(6).text()).toEqual('navigation.profile')
+
+ it('has first nav-item "navigation.transactions" in navbar', () => {
+ expect(wrapper.findAll('.nav-item').at(6).text()).toEqual('navigation.community')
})
+ it('has first nav-item "navigation.profile" in navbar', () => {
+ expect(wrapper.findAll('.nav-item').at(7).text()).toEqual('navigation.profile')
+ })
+ })
+
+ describe('navigation Navbar (user has an elopage account)', () => {
it('has a link to the members area', () => {
- expect(wrapper.findAll('.nav-item').at(7).text()).toContain('navigation.members_area')
- expect(wrapper.findAll('.nav-item').at(7).find('a').attributes('href')).toBe(
+ expect(wrapper.findAll('.nav-item').at(8).text()).toContain('navigation.members_area')
+ expect(wrapper.findAll('.nav-item').at(8).find('a').attributes('href')).toBe(
'https://elopage.com',
)
})
+ it('has first nav-item "navigation.admin_area" in navbar', () => {
+ expect(wrapper.findAll('.nav-item').at(9).text()).toEqual('navigation.admin_area')
+ })
+
+ it('has first nav-item "navigation.logout" in navbar', () => {
+ expect(wrapper.findAll('.nav-item').at(10).text()).toEqual('navigation.logout')
+ })
+ })
+
+ describe('navigation Navbar (user has no elopage account)', () => {
+ beforeAll(() => {
+ mocks.$store.state.hasElopage = false
+ wrapper = Wrapper()
+ })
+
it('has first nav-item "navigation.admin_area" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(8).text()).toEqual('navigation.admin_area')
})
+
it('has first nav-item "navigation.logout" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(9).text()).toEqual('navigation.logout')
})
})
})
+
describe('check watch visible true', () => {
beforeEach(async () => {
await wrapper.setProps({ visible: true })
diff --git a/frontend/src/components/Menu/Navbar.vue b/frontend/src/components/Menu/Navbar.vue
index 2f26f381e..ef222fdb4 100644
--- a/frontend/src/components/Menu/Navbar.vue
+++ b/frontend/src/components/Menu/Navbar.vue
@@ -52,17 +52,18 @@
{{ $t('navigation.transactions') }}
+
+
+ {{ $t('navigation.community') }}
+
{{ $t('navigation.profile') }}
-
+
{{ $t('navigation.members_area') }}
-
- {{ $t('math.exclaim') }}
-
diff --git a/frontend/src/components/Menu/Sidebar.spec.js b/frontend/src/components/Menu/Sidebar.spec.js
index f6051c733..1593a79a8 100644
--- a/frontend/src/components/Menu/Sidebar.spec.js
+++ b/frontend/src/components/Menu/Sidebar.spec.js
@@ -27,15 +27,12 @@ describe('Sidebar', () => {
beforeEach(() => {
wrapper = Wrapper()
})
+
it('renders the component', () => {
expect(wrapper.find('div#component-sidebar').exists()).toBeTruthy()
})
- describe('navigation Navbar', () => {
- it('has seven b-nav-item in the navbar', () => {
- expect(wrapper.findAll('.nav-item')).toHaveLength(8)
- })
-
+ describe('navigation Navbar (general elements)', () => {
it('has first nav-item "navigation.overview" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(0).text()).toEqual('navigation.overview')
})
@@ -55,6 +52,12 @@ describe('Sidebar', () => {
it('has first nav-item "navigation.profile" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(4).text()).toEqual('navigation.profile')
})
+ })
+
+ describe('navigation Navbar (user has an elopage account)', () => {
+ it('has eight b-nav-item in the navbar', () => {
+ expect(wrapper.findAll('.nav-item')).toHaveLength(8)
+ })
it('has a link to the members area', () => {
expect(wrapper.findAll('.nav-item').at(5).text()).toEqual('navigation.members_area')
@@ -69,5 +72,24 @@ describe('Sidebar', () => {
expect(wrapper.findAll('.nav-item').at(7).text()).toEqual('navigation.logout')
})
})
+
+ describe('navigation Navbar (user has no elopage account)', () => {
+ beforeAll(() => {
+ mocks.$store.state.hasElopage = false
+ wrapper = Wrapper()
+ })
+
+ it('has seven b-nav-item in the navbar', () => {
+ expect(wrapper.findAll('.nav-item')).toHaveLength(7)
+ })
+
+ it('has first nav-item "navigation.admin_area" in navbar', () => {
+ expect(wrapper.findAll('.nav-item').at(5).text()).toEqual('navigation.admin_area')
+ })
+
+ it('has first nav-item "navigation.logout" in navbar', () => {
+ expect(wrapper.findAll('.nav-item').at(6).text()).toEqual('navigation.logout')
+ })
+ })
})
})
diff --git a/frontend/src/components/Menu/Sidebar.vue b/frontend/src/components/Menu/Sidebar.vue
index b54eb541e..00243fa49 100644
--- a/frontend/src/components/Menu/Sidebar.vue
+++ b/frontend/src/components/Menu/Sidebar.vue
@@ -27,12 +27,14 @@
-
+
{{ $t('navigation.members_area') }}
-
- {{ $t('math.exclaim') }}
-
diff --git a/frontend/src/components/TransactionLinks/TransactionLink.vue b/frontend/src/components/TransactionLinks/TransactionLink.vue
index 5618c8696..76f705e35 100644
--- a/frontend/src/components/TransactionLinks/TransactionLink.vue
+++ b/frontend/src/components/TransactionLinks/TransactionLink.vue
@@ -18,17 +18,17 @@
-
+
- {{ $t('gdd_per_link.copy') }}
+ {{ $t('gdd_per_link.copy-link') }}
- {{ $t('gdd_per_link.copy-with-text') }}
+ {{ $t('gdd_per_link.copy-link-with-text') }}
{
- this.toastSuccess(this.$t('gdd_per_link.link-copied'))
- })
- .catch(() => {
- this.$bvModal.show('modalPopoverCopyError' + this.id)
- 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}"
-${this.$t('gdd_per_link.credit-your-gradido')} ${this.$t('gdd_per_link.validUntilDate', {
- date: this.$d(new Date(this.validUntil), 'short'),
- })}`,
- )
- .then(() => {
- this.toastSuccess(this.$t('gdd_per_link.link-and-text-copied'))
- })
- .catch(() => {
- this.$bvModal.show('modalPopoverCopyError' + this.id)
- this.toastError(this.$t('gdd_per_link.not-copied'))
- })
- },
deleteLink() {
this.$bvModal.msgBoxConfirm(this.$t('gdd_per_link.delete-the-link')).then(async (value) => {
if (value)
diff --git a/frontend/src/graphql/mutations.js b/frontend/src/graphql/mutations.js
index ec1f5a410..959bdefc3 100644
--- a/frontend/src/graphql/mutations.js
+++ b/frontend/src/graphql/mutations.js
@@ -74,6 +74,9 @@ export const createTransactionLink = gql`
mutation($amount: Decimal!, $memo: String!) {
createTransactionLink(amount: $amount, memo: $memo) {
link
+ amount
+ memo
+ validUntil
}
}
`
diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json
index 0deec9ae1..422a445bd 100644
--- a/frontend/src/locales/de.json
+++ b/frontend/src/locales/de.json
@@ -26,7 +26,7 @@
"community": "Gemeinschaft",
"continue-to-registration": "Weiter zur Registrierung",
"current-community": "Aktuelle Gemeinschaft",
- "myContributions": "Meine BeitrÀge",
+ "myContributions": "Meine BeitrÀge zum Gemeinwohl",
"other-communities": "Weitere Gemeinschaften",
"submitContribution": "Beitrag einreichen",
"switch-to-this-community": "zu dieser Gemeinschaft wechseln"
@@ -36,11 +36,12 @@
"alert": {
"communityNoteList": "Hier findest du alle eingereichten und bestÀtigten BeitrÀge von allen Mitgliedern aus dieser Gemeinschaft.",
"confirm": "bestÀtigt",
- "myContributionNoteList": "Hier findest du chronologisch aufgelistet alle deine eingereichten BeitrÀge. Es gibt drei Darstellungsarten. Du kannst deine BeitrÀge, welche noch nicht bestÀtigt wurden, jederzeit bearbeiten.",
+ "myContributionNoteList": "Eingereichte BeitrÀge, die noch nicht bestÀtigt wurden, kannst du jederzeit bearbeiten oder löschen.",
"myContributionNoteSupport": "Es wird bald an dieser Stelle die Möglichkeit geben das ein Dialog zwischen Moderatoren und dir stattfinden kann. Solltest du jetzt Probleme haben bitte nimm Kontakt mit dem Support auf.",
"pending": "Eingereicht und wartet auf BestÀtigung",
"rejected": "abgelehnt"
},
+ "date": "Beitrag fĂŒr:",
"delete": "Beitrag löschen! Bist du sicher?",
"deleted": "Der Beitrag wurde gelöscht! Wird aber sichtbar bleiben.",
"formText": {
@@ -150,8 +151,8 @@
"GDD": "GDD",
"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.",
- "copy": "kopieren",
- "copy-with-text": "Link und Text kopieren",
+ "copy-link": "Link kopieren",
+ "copy-link-with-text": "Link und Text kopieren",
"created": "Der Link wurde erstellt!",
"credit-your-gradido": "Damit die Gradido gutgeschrieben werden können, klicke auf den Link!",
"decay-14-day": "VergĂ€nglichkeit fĂŒr 14 Tage",
@@ -203,10 +204,7 @@
"login": "Anmeldung",
"math": {
"aprox": "~",
- "divide": "/",
"equal": "=",
- "exclaim": "!",
- "lower": "<",
"minus": "â",
"pipe": "|"
},
diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json
index 65b7abc87..89c18a106 100644
--- a/frontend/src/locales/en.json
+++ b/frontend/src/locales/en.json
@@ -26,7 +26,7 @@
"community": "Community",
"continue-to-registration": "Continue to registration",
"current-community": "Current community",
- "myContributions": "My contributions",
+ "myContributions": "My contributions to the common good",
"other-communities": "Other communities",
"submitContribution": "Submit contribution",
"switch-to-this-community": "Switch to this community"
@@ -36,11 +36,12 @@
"alert": {
"communityNoteList": "Here you will find all submitted and confirmed contributions from all members of this community.",
"confirm": "confirmed",
- "myContributionNoteList": "Here you will find a chronological list of all your submitted contributions. There are three display types. There are three ways of displaying your posts. You can edit your contributions, which have not yet been confirmed, at any time.",
+ "myContributionNoteList": "You can edit or delete entries that have not yet been confirmed at any time.",
"myContributionNoteSupport": "Soon there will be the possibility for a dialogue between moderators and you. If you have any problems now, please contact the support.",
"pending": "Submitted and waiting for confirmation",
"rejected": "deleted"
},
+ "date": "Contribution for:",
"delete": "Delete Contribution! Are you sure?",
"deleted": "The contribution has been deleted! But it will remain visible.",
"formText": {
@@ -150,8 +151,8 @@
"GDD": "GDD",
"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.",
- "copy": "copy",
- "copy-with-text": "Copy link and text",
+ "copy-link": "Copy link",
+ "copy-link-with-text": "Copy link and text",
"created": "Link was created!",
"credit-your-gradido": "For the Gradido to be credited, click on the link!",
"decay-14-day": "Decay for 14 days",
@@ -203,10 +204,7 @@
"login": "Login",
"math": {
"aprox": "~",
- "divide": "/",
"equal": "=",
- "exclaim": "!",
- "lower": "<",
"minus": "â",
"pipe": "|"
},
diff --git a/frontend/src/mixins/copyLinks.js b/frontend/src/mixins/copyLinks.js
new file mode 100644
index 000000000..415358c9b
--- /dev/null
+++ b/frontend/src/mixins/copyLinks.js
@@ -0,0 +1,44 @@
+export const copyLinks = {
+ props: {
+ link: { type: String, required: true },
+ amount: { type: String, required: true },
+ memo: { type: String, required: true },
+ validUntil: { type: String, required: true },
+ },
+ data() {
+ return {
+ canCopyLink: true,
+ }
+ },
+ methods: {
+ copyLink() {
+ navigator.clipboard
+ .writeText(this.link)
+ .then(() => {
+ this.toastSuccess(this.$t('gdd_per_link.link-copied'))
+ })
+ .catch(() => {
+ this.canCopyLink = false
+ 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}"
+${this.$t('gdd_per_link.credit-your-gradido')} ${this.$t('gdd_per_link.validUntilDate', {
+ date: this.$d(new Date(this.validUntil), 'short'),
+ })}`,
+ )
+ .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'))
+ })
+ },
+ },
+}
diff --git a/frontend/src/pages/Community.spec.js b/frontend/src/pages/Community.spec.js
index 24260addf..b4aa43785 100644
--- a/frontend/src/pages/Community.spec.js
+++ b/frontend/src/pages/Community.spec.js
@@ -26,6 +26,9 @@ describe('Community', () => {
creation: ['1000', '1000', '1000'],
},
},
+ $i18n: {
+ locale: 'en',
+ },
}
const Wrapper = () => {
diff --git a/frontend/src/pages/Send.spec.js b/frontend/src/pages/Send.spec.js
index 47a30ff65..0738d9720 100644
--- a/frontend/src/pages/Send.spec.js
+++ b/frontend/src/pages/Send.spec.js
@@ -25,9 +25,11 @@ describe('Send', () => {
const mocks = {
$t: jest.fn((t) => t),
$n: jest.fn((n) => String(n)),
+ $d: jest.fn((d) => d),
$store: {
state: {
email: 'sender@example.org',
+ firstName: 'Testy',
},
},
$apollo: {
@@ -160,11 +162,15 @@ describe('Send', () => {
})
describe('transaction form link', () => {
+ const now = new Date().toISOString()
beforeEach(async () => {
apolloMutationMock.mockResolvedValue({
data: {
createTransactionLink: {
link: 'http://localhost/redeem/0123456789',
+ amount: '56.78',
+ memo: 'Make the best of the link!',
+ validUntil: now,
},
},
})
@@ -228,18 +234,64 @@ describe('Send', () => {
navigator.clipboard = navigatorClipboard
})
- describe('copy with success', () => {
+ describe('copy link with success', () => {
beforeEach(async () => {
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', () => {
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!"\n' +
+ 'gdd_per_link.credit-your-gradido gdd_per_link.validUntilDate',
+ )
+ })
+ it('toasts success message', () => {
+ expect(toastSuccessSpy).toBeCalledWith('gdd_per_link.link-and-text-copied')
+ })
+ })
+
+ describe('copy link and text with error', () => {
beforeEach(async () => {
navigatorClipboardMock.mockRejectedValue()
await wrapper.findAll('button').at(0).trigger('click')
@@ -253,7 +305,7 @@ describe('Send', () => {
describe('close button click', () => {
beforeEach(async () => {
- await wrapper.findAll('button').at(2).trigger('click')
+ await wrapper.findAll('button').at(3).trigger('click')
})
it('Shows the TransactionForm', () => {
diff --git a/frontend/src/pages/Send.vue b/frontend/src/pages/Send.vue
index cd5f8f572..74e2b0270 100644
--- a/frontend/src/pages/Send.vue
+++ b/frontend/src/pages/Send.vue
@@ -41,7 +41,13 @@
>
-
+
@@ -144,7 +150,15 @@ export default {
})
.then((result) => {
this.$emit('set-tunneled-email', null)
- this.link = result.data.createTransactionLink.link
+ const {
+ data: {
+ createTransactionLink: { link, amount, memo, validUntil },
+ },
+ } = result
+ this.link = link
+ this.amount = amount
+ this.memo = memo
+ this.validUntil = validUntil
this.transactionData = { ...EMPTY_TRANSACTION_DATA }
this.currentTransactionStep = TRANSACTION_STEPS.transactionResultLink
this.updateTransactions({})
diff --git a/package.json b/package.json
index bf8eced01..2bba1b52c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "gradido",
- "version": "1.10.1",
+ "version": "1.11.0",
"description": "Gradido",
"main": "index.js",
"repository": "git@github.com:gradido/gradido.git",