diff --git a/CHANGELOG.md b/CHANGELOG.md index 63b0c2c90..352286e45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,49 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [1.12.0](https://github.com/gradido/gradido/compare/1.11.0...1.12.0) + +- if message empty else disabled button [`#2189`](https://github.com/gradido/gradido/pull/2189) +- messages show if Confirmed [`#2185`](https://github.com/gradido/gradido/pull/2185) +- text in messages smaller [`#2186`](https://github.com/gradido/gradido/pull/2186) +- feat: 🍰 Klicktipp retrieve not registered email [`#2181`](https://github.com/gradido/gradido/pull/2181) +- fix: 🍰 isModerator on messages to switch the messages side in the messages overview [`#2182`](https://github.com/gradido/gradido/pull/2182) +- Refactor locales for Nederlands [`#2174`](https://github.com/gradido/gradido/pull/2174) +- Add is moderator to contribution message [`#2180`](https://github.com/gradido/gradido/pull/2180) +- feat: 🍰 Moderator Cannot Answer Himself [`#2178`](https://github.com/gradido/gradido/pull/2178) +- refactor: Improve Statistics Query [`#2170`](https://github.com/gradido/gradido/pull/2170) +- fix: Remove Statistics from Wallet [`#2171`](https://github.com/gradido/gradido/pull/2171) +- feat: 🍰 Contribution Messages In Frontend [`#2164`](https://github.com/gradido/gradido/pull/2164) +- feat: 🚀 CRUD For Contribution Messages [`#2149`](https://github.com/gradido/gradido/pull/2149) +- fix: 🍰 Decay Calculation In Community Statistics [`#2167`](https://github.com/gradido/gradido/pull/2167) +- chore: 🍰 Remove Fetch Policy Network Only From Statistics [`#2159`](https://github.com/gradido/gradido/pull/2159) +- feat: 🍰 Remove Some Statistics Data From Frontend [`#2153`](https://github.com/gradido/gradido/pull/2153) +- feat: 🍰 Add Toogle Collaps On Language Name [`#2156`](https://github.com/gradido/gradido/pull/2156) +- 2145 corrections style for frontend [`#2147`](https://github.com/gradido/gradido/pull/2147) +- 2072 feature usecase contribution messaging [`#2073`](https://github.com/gradido/gradido/pull/2073) +- 2151 add hint to redeem link [`#2158`](https://github.com/gradido/gradido/pull/2158) +- 🍰 Create `contribution messages` table [`#2137`](https://github.com/gradido/gradido/pull/2137) +- feat: 🍰 Add The Languages French And Dutch [`#2138`](https://github.com/gradido/gradido/pull/2138) +- 1973 list open contribution links in the wallet [`#1975`](https://github.com/gradido/gradido/pull/1975) +- feat: 🍰 Admin Interface Displays Statistics [`#2124`](https://github.com/gradido/gradido/pull/2124) +- feat: Statistics Resolver [`#2041`](https://github.com/gradido/gradido/pull/2041) +- 2116 retrieve admin and moderators [`#2127`](https://github.com/gradido/gradido/pull/2127) +- 2125 feature gradido id: new column gradidoid in users table [`#2126`](https://github.com/gradido/gradido/pull/2126) +- 2119 new menu item gdt [`#2120`](https://github.com/gradido/gradido/pull/2120) +- feat: Migrate Contributions Table [`#2136`](https://github.com/gradido/gradido/pull/2136) +- chore: 🍰 Refactor Contribution Form Logic And Write Tests [`#2092`](https://github.com/gradido/gradido/pull/2092) +- fix: 🍰 Add `emailChecked` Before Changing `optIn` State & Log Error On klicktipp Middleware [`#2107`](https://github.com/gradido/gradido/pull/2107) +- Add RIGHTS.LIST_CONTRIBUTION_LINKS to ROLE_USER [`#2123`](https://github.com/gradido/gradido/pull/2123) +- 2121 translate locales to spanish [`#2122`](https://github.com/gradido/gradido/pull/2122) +- add formatter on input amount replace point and comma [`#2115`](https://github.com/gradido/gradido/pull/2115) +- remove required from form.memo [`#2114`](https://github.com/gradido/gradido/pull/2114) +- Fix pagination ellipsis [`#2104`](https://github.com/gradido/gradido/pull/2104) + #### [1.11.0](https://github.com/gradido/gradido/compare/1.10.1...1.11.0) +> 28 July 2022 + +- release: Version 1.11.0 [`#2103`](https://github.com/gradido/gradido/pull/2103) - Fix navbar community item [`#2102`](https://github.com/gradido/gradido/pull/2102) - Add validation date info to copied text after transaction link creation [`#2101`](https://github.com/gradido/gradido/pull/2101) - Remove member area from menu (desktop and mobile), when user has no elopage account [`#2099`](https://github.com/gradido/gradido/pull/2099) diff --git a/admin/package.json b/admin/package.json index 9879064de..f31b43bbd 100644 --- a/admin/package.json +++ b/admin/package.json @@ -3,7 +3,7 @@ "description": "Administraion Interface for Gradido", "main": "index.js", "author": "Moriz Wahl", - "version": "1.11.0", + "version": "1.12.0", "license": "Apache-2.0", "private": false, "scripts": { diff --git a/admin/src/components/ContributionMessages/ContributionMessagesFormular.spec.js b/admin/src/components/ContributionMessages/ContributionMessagesFormular.spec.js new file mode 100644 index 000000000..62fcab505 --- /dev/null +++ b/admin/src/components/ContributionMessages/ContributionMessagesFormular.spec.js @@ -0,0 +1,111 @@ +import { mount } from '@vue/test-utils' +import ContributionMessagesFormular from './ContributionMessagesFormular.vue' +import { toastErrorSpy, toastSuccessSpy } from '../../../test/testSetup' + +const localVue = global.localVue + +const apolloMutateMock = jest.fn().mockResolvedValue() + +describe('ContributionMessagesFormular', () => { + let wrapper + + const propsData = { + contributionId: 42, + } + + const mocks = { + $t: jest.fn((t) => t), + $apollo: { + mutate: apolloMutateMock, + }, + $i18n: { + locale: 'en', + }, + } + + const Wrapper = () => { + return mount(ContributionMessagesFormular, { + localVue, + mocks, + propsData, + }) + } + + describe('mount', () => { + beforeEach(() => { + wrapper = Wrapper() + }) + + it('has a DIV .contribution-messages-formular', () => { + expect(wrapper.find('div.contribution-messages-formular').exists()).toBe(true) + }) + + describe('on trigger reset', () => { + beforeEach(async () => { + wrapper.setData({ + form: { + text: 'text form message', + }, + }) + await wrapper.find('form').trigger('reset') + }) + + it('form has empty text', () => { + expect(wrapper.vm.form).toEqual({ + text: '', + }) + }) + }) + + describe('on trigger submit', () => { + beforeEach(async () => { + wrapper.setData({ + form: { + text: 'text form message', + }, + }) + await wrapper.find('form').trigger('submit') + }) + + it('emitted "get-list-contribution-messages" with data', async () => { + expect(wrapper.emitted('get-list-contribution-messages')).toEqual( + expect.arrayContaining([expect.arrayContaining([42])]), + ) + }) + + it('emitted "update-state" with data', async () => { + expect(wrapper.emitted('update-state')).toEqual( + expect.arrayContaining([expect.arrayContaining([42])]), + ) + }) + }) + + describe('send contribution message with error', () => { + beforeEach(async () => { + apolloMutateMock.mockRejectedValue({ message: 'OUCH!' }) + wrapper = Wrapper() + await wrapper.find('form').trigger('submit') + }) + + it('toasts an error message', () => { + expect(toastErrorSpy).toBeCalledWith('OUCH!') + }) + }) + + describe('send contribution message with success', () => { + beforeEach(async () => { + wrapper.setData({ + form: { + text: 'text form message', + }, + }) + wrapper = Wrapper() + await wrapper.find('form').trigger('submit') + }) + + it('toasts an success message', () => { + expect(toastSuccessSpy).toBeCalledWith('message.request') + }) + }) + }) +}) diff --git a/admin/src/components/ContributionMessages/ContributionMessagesFormular.vue b/admin/src/components/ContributionMessages/ContributionMessagesFormular.vue new file mode 100644 index 000000000..a0e790abe --- /dev/null +++ b/admin/src/components/ContributionMessages/ContributionMessagesFormular.vue @@ -0,0 +1,77 @@ + + diff --git a/admin/src/components/ContributionMessages/ContributionMessagesList.spec.js b/admin/src/components/ContributionMessages/ContributionMessagesList.spec.js new file mode 100644 index 000000000..0bca08b2a --- /dev/null +++ b/admin/src/components/ContributionMessages/ContributionMessagesList.spec.js @@ -0,0 +1,56 @@ +import { mount } from '@vue/test-utils' +import ContributionMessagesList from './ContributionMessagesList.vue' + +const localVue = global.localVue + +const apolloQueryMock = jest.fn().mockResolvedValue() + +describe('ContributionMessagesList', () => { + let wrapper + + const propsData = { + contributionId: 42, + } + + const mocks = { + $t: jest.fn((t) => t), + $i18n: { + locale: 'en', + }, + $apollo: { + query: apolloQueryMock, + }, + } + + const Wrapper = () => { + return mount(ContributionMessagesList, { + localVue, + mocks, + propsData, + }) + } + + describe('mount', () => { + beforeEach(() => { + wrapper = Wrapper() + }) + + it('sends query to Apollo when created', () => { + expect(apolloQueryMock).toBeCalledWith( + expect.objectContaining({ + variables: { + contributionId: propsData.contributionId, + }, + }), + ) + }) + + it('has a DIV .contribution-messages-list', () => { + expect(wrapper.find('div.contribution-messages-list').exists()).toBe(true) + }) + + it('has a Component ContributionMessagesFormular', () => { + expect(wrapper.findComponent({ name: 'ContributionMessagesFormular' }).exists()).toBe(true) + }) + }) +}) diff --git a/admin/src/components/ContributionMessages/ContributionMessagesList.vue b/admin/src/components/ContributionMessages/ContributionMessagesList.vue new file mode 100644 index 000000000..8f5a3e119 --- /dev/null +++ b/admin/src/components/ContributionMessages/ContributionMessagesList.vue @@ -0,0 +1,69 @@ + + + diff --git a/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.spec.js b/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.spec.js new file mode 100644 index 000000000..7cca315d7 --- /dev/null +++ b/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.spec.js @@ -0,0 +1,58 @@ +import { mount } from '@vue/test-utils' +import ContributionMessagesListItem from './ContributionMessagesListItem.vue' + +const localVue = global.localVue + +describe('ContributionMessagesListItem', () => { + let wrapper + + const mocks = { + $t: jest.fn((t) => t), + $d: jest.fn((d) => d), + $store: { + state: { + moderator: { + id: 107, + }, + }, + }, + } + + const propsData = { + contributionId: 42, + state: 'PENDING0', + message: { + id: 111, + message: 'asd asda sda sda', + createdAt: '2022-08-29T12:23:27.000Z', + updatedAt: null, + type: 'DIALOG', + userFirstName: 'Peter', + userLastName: 'Lustig', + userId: 107, + __typename: 'ContributionMessage', + }, + } + + const Wrapper = () => { + return mount(ContributionMessagesListItem, { + localVue, + mocks, + propsData, + }) + } + + describe('mount', () => { + beforeEach(() => { + wrapper = Wrapper() + }) + + it('has a DIV .contribution-messages-list-item', () => { + expect(wrapper.find('div.contribution-messages-list-item').exists()).toBe(true) + }) + + it('props.message.default', () => { + expect(wrapper.vm.$options.props.message.default.call()).toEqual({}) + }) + }) +}) diff --git a/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.vue b/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.vue new file mode 100644 index 000000000..fa5bdd940 --- /dev/null +++ b/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.vue @@ -0,0 +1,27 @@ + + diff --git a/admin/src/components/ContributionMessages/slots/IsModerator.spec.js b/admin/src/components/ContributionMessages/slots/IsModerator.spec.js new file mode 100644 index 000000000..b1e09da94 --- /dev/null +++ b/admin/src/components/ContributionMessages/slots/IsModerator.spec.js @@ -0,0 +1,49 @@ +import { mount } from '@vue/test-utils' +import IsModerator from './IsModerator.vue' + +const localVue = global.localVue + +describe('IsModerator', () => { + let wrapper + + const mocks = { + $t: jest.fn((t) => t), + $d: jest.fn((d) => d), + } + + const propsData = { + message: { + id: 111, + message: 'asd asda sda sda', + createdAt: '2022-08-29T12:23:27.000Z', + updatedAt: null, + type: 'DIALOG', + userFirstName: 'Peter', + userLastName: 'Lustig', + userId: 107, + __typename: 'ContributionMessage', + }, + } + + const Wrapper = () => { + return mount(IsModerator, { + localVue, + mocks, + propsData, + }) + } + + describe('mount', () => { + beforeEach(() => { + wrapper = Wrapper() + }) + + it('has a DIV .slot-is-moderator', () => { + expect(wrapper.find('div.slot-is-moderator').exists()).toBe(true) + }) + + it('props.message.default', () => { + expect(wrapper.vm.$options.props.message.default.call()).toEqual({}) + }) + }) +}) diff --git a/admin/src/components/ContributionMessages/slots/IsModerator.vue b/admin/src/components/ContributionMessages/slots/IsModerator.vue new file mode 100644 index 000000000..0224e042f --- /dev/null +++ b/admin/src/components/ContributionMessages/slots/IsModerator.vue @@ -0,0 +1,37 @@ + + + diff --git a/admin/src/components/ContributionMessages/slots/IsNotModerator.spec.js b/admin/src/components/ContributionMessages/slots/IsNotModerator.spec.js new file mode 100644 index 000000000..24152ad1e --- /dev/null +++ b/admin/src/components/ContributionMessages/slots/IsNotModerator.spec.js @@ -0,0 +1,49 @@ +import { mount } from '@vue/test-utils' +import IsNotModerator from './IsNotModerator.vue' + +const localVue = global.localVue + +describe('IsNotModerator', () => { + let wrapper + + const mocks = { + $t: jest.fn((t) => t), + $d: jest.fn((d) => d), + } + + const propsData = { + message: { + id: 113, + message: 'asda sdad ad asdasd ', + createdAt: '2022-08-29T12:25:34.000Z', + updatedAt: null, + type: 'DIALOG', + userFirstName: 'Bibi', + userLastName: 'Bloxberg', + userId: 108, + __typename: 'ContributionMessage', + }, + } + + const Wrapper = () => { + return mount(IsNotModerator, { + localVue, + mocks, + propsData, + }) + } + + describe('mount', () => { + beforeEach(() => { + wrapper = Wrapper() + }) + + it('has a DIV .slot-is-not-moderator', () => { + expect(wrapper.find('div.slot-is-not-moderator').exists()).toBe(true) + }) + + it('props.message.default', () => { + expect(wrapper.vm.$options.props.message.default.call()).toEqual({}) + }) + }) +}) diff --git a/admin/src/components/ContributionMessages/slots/IsNotModerator.vue b/admin/src/components/ContributionMessages/slots/IsNotModerator.vue new file mode 100644 index 000000000..64946c557 --- /dev/null +++ b/admin/src/components/ContributionMessages/slots/IsNotModerator.vue @@ -0,0 +1,34 @@ + + + diff --git a/admin/src/components/Tables/OpenCreationsTable.vue b/admin/src/components/Tables/OpenCreationsTable.vue index 3ebc81fba..af9947f85 100644 --- a/admin/src/components/Tables/OpenCreationsTable.vue +++ b/admin/src/components/Tables/OpenCreationsTable.vue @@ -12,20 +12,42 @@ diff --git a/frontend/src/components/LanguageSwitch.spec.js b/frontend/src/components/LanguageSwitch.spec.js index a6abc2359..7f37c535a 100644 --- a/frontend/src/components/LanguageSwitch.spec.js +++ b/frontend/src/components/LanguageSwitch.spec.js @@ -45,7 +45,7 @@ describe('LanguageSwitch', () => { expect(wrapper.find('div.language-switch').exists()).toBeTruthy() }) - describe('with locales en, de and es', () => { + describe('with locales en, de, es, fr, and nl', () => { describe('empty store', () => { describe('navigator language is "en-US"', () => { const languageGetter = jest.spyOn(navigator, 'language', 'get') @@ -94,11 +94,11 @@ describe('LanguageSwitch', () => { describe('navigator language is "nl-NL"', () => { const languageGetter = jest.spyOn(navigator, 'language', 'get') - it('shows Dutch as language ', async () => { + it('shows Nederlands as language ', async () => { languageGetter.mockReturnValue('nl-NL') wrapper.vm.setCurrentLanguage() await wrapper.vm.$nextTick() - expect(wrapper.find('button.dropdown-toggle').text()).toBe('Holandés - nl') + expect(wrapper.find('button.dropdown-toggle').text()).toBe('Nederlands - nl') }) }) @@ -153,16 +153,16 @@ describe('LanguageSwitch', () => { }) describe('language "nl" in store', () => { - it('shows Dutch as language', async () => { + it('shows Nederlands as language', async () => { wrapper.vm.$store.state.language = 'nl' wrapper.vm.setCurrentLanguage() await wrapper.vm.$nextTick() - expect(wrapper.find('button.dropdown-toggle').text()).toBe('Holandés - nl') + expect(wrapper.find('button.dropdown-toggle').text()).toBe('Nederlands - nl') }) }) describe('dropdown menu', () => { - it('has English and German as languages to choose', () => { + it('has five languages to choose from', () => { expect(wrapper.findAll('li')).toHaveLength(5) }) @@ -174,16 +174,16 @@ describe('LanguageSwitch', () => { expect(wrapper.findAll('li').at(1).text()).toBe('Deutsch') }) - it('has Español as second language to choose', () => { + it('has Español as third language to choose', () => { expect(wrapper.findAll('li').at(2).text()).toBe('Español') }) - it('has French as second language to choose', () => { + it('has French as fourth language to choose', () => { expect(wrapper.findAll('li').at(3).text()).toBe('Français') }) - it('has Dutch as second language to choose', () => { - expect(wrapper.findAll('li').at(4).text()).toBe('Holandés') + it('has Nederlands as fith language to choose', () => { + expect(wrapper.findAll('li').at(4).text()).toBe('Nederlands') }) }) }) diff --git a/frontend/src/components/LanguageSwitch2.spec.js b/frontend/src/components/LanguageSwitch2.spec.js index 080cc9d42..0d2b485ec 100644 --- a/frontend/src/components/LanguageSwitch2.spec.js +++ b/frontend/src/components/LanguageSwitch2.spec.js @@ -46,10 +46,11 @@ describe('LanguageSwitch', () => { expect(wrapper.find('div.language-switch').exists()).toBe(true) }) - describe('with locales en and de', () => { + describe('with locales en, de, es, fr, and nl', () => { describe('empty store', () => { describe('navigator language is "en-US"', () => { const languageGetter = jest.spyOn(navigator, 'language', 'get') + it('shows English as default navigator langauge', async () => { languageGetter.mockReturnValue('en-US') wrapper.vm.setCurrentLanguage() @@ -57,8 +58,10 @@ describe('LanguageSwitch', () => { expect(wrapper.findAll('span.locales').at(0).text()).toBe('English') }) }) + describe('navigator language is "de-DE"', () => { const languageGetter = jest.spyOn(navigator, 'language', 'get') + it('shows Deutsch as language ', async () => { languageGetter.mockReturnValue('de-DE') wrapper.vm.setCurrentLanguage() @@ -66,8 +69,10 @@ describe('LanguageSwitch', () => { expect(wrapper.findAll('span.locales').at(1).text()).toBe('Deutsch') }) }) + describe('navigator language is "es-ES"', () => { const languageGetter = jest.spyOn(navigator, 'language', 'get') + it('shows Español as language ', async () => { languageGetter.mockReturnValue('es-ES') wrapper.vm.setCurrentLanguage() @@ -75,8 +80,10 @@ describe('LanguageSwitch', () => { expect(wrapper.findAll('span.locales').at(2).text()).toBe('Español') }) }) + describe('navigator language is "fr-FR"', () => { const languageGetter = jest.spyOn(navigator, 'language', 'get') + it('shows French as language ', async () => { languageGetter.mockReturnValue('fr-FR') wrapper.vm.setCurrentLanguage() @@ -84,17 +91,21 @@ describe('LanguageSwitch', () => { expect(wrapper.findAll('span.locales').at(3).text()).toBe('Français') }) }) + describe('navigator language is "nl-NL"', () => { const languageGetter = jest.spyOn(navigator, 'language', 'get') - it('shows Dutch as language ', async () => { + + it('shows Nederlands as language ', async () => { languageGetter.mockReturnValue('nl-NL') wrapper.vm.setCurrentLanguage() await wrapper.vm.$nextTick() - expect(wrapper.findAll('span.locales').at(4).text()).toBe('Holandés') + expect(wrapper.findAll('span.locales').at(4).text()).toBe('Nederlands') }) }) + describe('navigator language is "it-IT" (not supported)', () => { const languageGetter = jest.spyOn(navigator, 'language', 'get') + it('shows English as language ', async () => { languageGetter.mockReturnValue('it-IT') wrapper.vm.setCurrentLanguage() @@ -102,8 +113,10 @@ describe('LanguageSwitch', () => { expect(wrapper.findAll('span.locales').at(0).text()).toBe('English') }) }) + describe('no navigator langauge', () => { const languageGetter = jest.spyOn(navigator, 'language', 'get') + it('shows English as language ', async () => { languageGetter.mockReturnValue(null) wrapper.vm.setCurrentLanguage() @@ -112,6 +125,7 @@ describe('LanguageSwitch', () => { }) }) }) + describe('language "de" in store', () => { it('shows Deutsch as language', async () => { wrapper.vm.$store.state.language = 'de' @@ -120,6 +134,7 @@ describe('LanguageSwitch', () => { expect(wrapper.findAll('span.locales').at(1).text()).toBe('English') }) }) + describe('language "es" in store', () => { it('shows Español as language', async () => { wrapper.vm.$store.state.language = 'es' @@ -128,6 +143,7 @@ describe('LanguageSwitch', () => { expect(wrapper.findAll('span.locales').at(2).text()).toBe('Deutsch') }) }) + describe('language "fr" in store', () => { it('shows French as language', async () => { wrapper.vm.$store.state.language = 'fr' @@ -136,43 +152,77 @@ describe('LanguageSwitch', () => { expect(wrapper.findAll('span.locales').at(3).text()).toBe('Español') }) }) + describe('language "nl" in store', () => { - it('shows Dutch as language', async () => { + it('shows Nederlands as language', async () => { wrapper.vm.$store.state.language = 'nl' wrapper.vm.setCurrentLanguage() await wrapper.vm.$nextTick() expect(wrapper.findAll('span.locales').at(4).text()).toBe('Français') }) }) + describe('language menu', () => { - it('has English, German and Español as languages to choose', () => { + beforeAll(async () => { + wrapper.vm.$store.state.language = 'en' + wrapper.vm.setCurrentLanguage() + await wrapper.vm.$nextTick() + }) + + it('has five languages to choose from', () => { expect(wrapper.findAll('span.locales')).toHaveLength(5) }) + it('has English as first language to choose', () => { - expect(wrapper.findAll('span.locales').at(0).text()).toBe('Holandés') + expect(wrapper.findAll('span.locales').at(0).text()).toBe('English') }) - it('has German as second language to choose', () => { - expect(wrapper.findAll('span.locales').at(1).text()).toBe('English') + + it('has Deutsch as second language to choose', () => { + expect(wrapper.findAll('span.locales').at(1).text()).toBe('Deutsch') }) + it('has Español as third language to choose', () => { - expect(wrapper.findAll('span.locales').at(2).text()).toBe('Deutsch') + expect(wrapper.findAll('span.locales').at(2).text()).toBe('Español') }) - it('has French as third language to choose', () => { - expect(wrapper.findAll('span.locales').at(3).text()).toBe('Español') + + it('has Français as fourth language to choose', () => { + expect(wrapper.findAll('span.locales').at(3).text()).toBe('Français') }) - it('has Dutch as third language to choose', () => { - expect(wrapper.findAll('span.locales').at(4).text()).toBe('Français') + + it('has Nederlands as fifth language to choose', () => { + expect(wrapper.findAll('span.locales').at(4).text()).toBe('Nederlands') }) }) }) describe('calls the API', () => { it("with locale 'de'", () => { - wrapper.findAll('span.locales').at(2).trigger('click') + wrapper.findAll('span.locales').at(1).trigger('click') expect(updateUserInfosMutationMock).toBeCalledWith( expect.objectContaining({ variables: { locale: 'de' } }), ) }) + + it("with locale 'es'", () => { + wrapper.findAll('span.locales').at(2).trigger('click') + expect(updateUserInfosMutationMock).toBeCalledWith( + expect.objectContaining({ variables: { locale: 'es' } }), + ) + }) + + it("with locale 'fr'", () => { + wrapper.findAll('span.locales').at(3).trigger('click') + expect(updateUserInfosMutationMock).toBeCalledWith( + expect.objectContaining({ variables: { locale: 'fr' } }), + ) + }) + + it("with locale 'nl'", () => { + wrapper.findAll('span.locales').at(4).trigger('click') + expect(updateUserInfosMutationMock).toBeCalledWith( + expect.objectContaining({ variables: { locale: 'nl' } }), + ) + }) }) }) }) diff --git a/frontend/src/graphql/mutations.js b/frontend/src/graphql/mutations.js index 959bdefc3..9846784d5 100644 --- a/frontend/src/graphql/mutations.js +++ b/frontend/src/graphql/mutations.js @@ -122,3 +122,17 @@ export const deleteContribution = gql` deleteContribution(id: $id) } ` + +export const createContributionMessage = gql` + mutation($contributionId: Float!, $message: String!) { + createContributionMessage(contributionId: $contributionId, message: $message) { + id + message + createdAt + updatedAt + type + userFirstName + userLastName + } + } +` diff --git a/frontend/src/graphql/queries.js b/frontend/src/graphql/queries.js index 03299dd49..07b016d0a 100644 --- a/frontend/src/graphql/queries.js +++ b/frontend/src/graphql/queries.js @@ -206,6 +206,8 @@ export const listContributions = gql` confirmedAt confirmedBy deletedAt + state + messagesCount } } } @@ -255,3 +257,26 @@ export const searchAdminUsers = gql` } } ` + +export const listContributionMessages = gql` + query($contributionId: Float!, $pageSize: Int = 25, $currentPage: Int = 1, $order: Order = ASC) { + listContributionMessages( + contributionId: $contributionId + pageSize: $pageSize + currentPage: $currentPage + order: $order + ) { + count + messages { + id + message + createdAt + updatedAt + type + userFirstName + userLastName + userId + } + } + } +` diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index 7c9f37370..e6b12b0fa 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -21,23 +21,23 @@ "community": "Gemeinschaft", "continue-to-registration": "Weiter zur Registrierung", "current-community": "Aktuelle Gemeinschaft", - "members": "Mitglieder", + "moderator": "Moderator", "moderators": "Moderatoren", "myContributions": "Meine Beiträge zum Gemeinwohl", "openContributionLinks": "öffentliche Beitrags-Linkliste", "openContributionLinkText": "Folgende {count} automatische Schöpfungen werden zur Zeit durch die Gemeinschaft „{name}“ bereitgestellt.", "other-communities": "Weitere Gemeinschaften", - "statistic": "Statistik", "submitContribution": "Beitrag einreichen", "switch-to-this-community": "zu dieser Gemeinschaft wechseln" }, "contribution": { "activity": "Tätigkeit", "alert": { + "answerQuestion": "Bitte beantworte die Nachfrage", "communityNoteList": "Hier findest du alle eingereichten und bestätigten Beiträge von allen Mitgliedern aus dieser Gemeinschaft.", "confirm": "bestätigt", + "in_progress": "Es gibt eine Rückfrage der Moderatoren.", "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" }, @@ -130,6 +130,7 @@ "password_new_repeat": "Neues Passwort wiederholen", "password_old": "Altes Passwort", "recipient": "Empfänger", + "reply": "Antworten", "reset": "Zurücksetzen", "save": "Speichern", "scann_code": "QR Code Scanner - Scanne den QR Code deines Partners", @@ -219,6 +220,7 @@ "email": "Wir haben dir eine E-Mail gesendet.", "errorTitle": "Achtung!", "register": "Du bist jetzt registriert, bitte überprüfe deine Emails und klicke auf den Aktivierungslink.", + "reply": "Danke, Deine Antwort wurde abgesendet.", "reset": "Dein Passwort wurde geändert.", "title": "Danke!", "unsetPassword": "Dein Passwort wurde noch nicht gesetzt. Bitte setze es neu." @@ -251,7 +253,7 @@ "en": "English", "es": "Español", "fr": "Français", - "nl": "Dutch", + "nl": "Nederlands", "success": "Deine Sprache wurde erfolgreich geändert." }, "name": { @@ -303,11 +305,6 @@ "uppercase": "Großbuchstabe erforderlich." } }, - "statistic": { - "totalGradidoAvailable": "GDD insgesamt im Umlauf", - "totalGradidoCreated": "GDD insgesamt geschöpft", - "totalGradidoDecayed": "GDD insgesamt verfallen" - }, "success": "Erfolg", "time": { "days": "Tage", diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 8fe5f31ad..07125eceb 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -21,23 +21,23 @@ "community": "Community", "continue-to-registration": "Continue to registration", "current-community": "Current community", - "members": "Members", + "moderator": "Moderator", "moderators": "Moderators", "myContributions": "My contributions to the common good", "openContributionLinks": "open Contribution links list", "openContributionLinkText": "The following {count} automatic creations are currently provided by the \"{name}\" community.", "other-communities": "Other communities", - "statistic": "Statistics", "submitContribution": "Submit contribution", "switch-to-this-community": "Switch to this community" }, "contribution": { "activity": "Activity", "alert": { + "answerQuestion": "Please answer the question", "communityNoteList": "Here you will find all submitted and confirmed contributions from all members of this community.", "confirm": "confirmed", + "in_progress": "There is a question from the moderators.", "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" }, @@ -130,6 +130,7 @@ "password_new_repeat": "Repeat new password", "password_old": "Old password", "recipient": "Recipient", + "reply": "Reply", "reset": "Reset", "save": "Save", "scann_code": "QR Code Scanner - Scan the QR Code of your partner", @@ -219,6 +220,7 @@ "email": "We have sent you an email.", "errorTitle": "Attention!", "register": "You are registered now, please check your emails and click the activation link.", + "reply": "Thank you, your reply has been sent.", "reset": "Your password has been changed.", "title": "Thank you!", "unsetPassword": "Your password has not been set yet. Please set it again." @@ -251,7 +253,7 @@ "en": "English", "es": "Español", "fr": "Français", - "nl": "Holandés", + "nl": "Nederlands", "success": "Your language has been successfully updated." }, "name": { @@ -303,11 +305,6 @@ "uppercase": "One uppercase letter required." } }, - "statistic": { - "totalGradidoAvailable": "Total GDD in circulation", - "totalGradidoCreated": "Total GDD created", - "totalGradidoDecayed": "Total GDD decayed" - }, "success": "Success", "time": { "days": "Days", diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index f95344b23..987bb71ef 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -22,6 +22,7 @@ "continue-to-registration": "Continuar con el registro", "current-community": "Comunidad actual", "members": "Miembros", + "moderator": "Moderador", "moderators": "Moderadores", "myContributions": "Mis contribuciones al bien común", "openContributionLinks": "lista de enlaces de contribuciones públicas", @@ -34,10 +35,11 @@ "contribution": { "activity": "Actividad", "alert": { + "answerQuestion": "Por favor, contesta las preguntas", "communityNoteList": "Aquí encontrarás todas las contribuciones enviadas y confirmadas de todos los miembros de esta comunidad.", "confirm": "confirmado", + "in_progress": "Hay una pregunta de los moderatores.", "myContributionNoteList": "Puedes editar o eliminar las contribuciones enviadas que aún no han sido confirmadas en cualquier momento.", - "myContributionNoteSupport": "Pronto existirá la posibilidad de que puedas dialogar con los moderadores. Si tienes algún problema ahora, ponte en contacto con el equipo de asistencia.", "pending": "Enviado y a la espera de confirmación", "rejected": "rechazado" }, @@ -130,6 +132,7 @@ "password_new_repeat": "Repetir contraseña nueva", "password_old": "contraseña antigua", "recipient": "Destinatario", + "reply": "Respuesta", "reset": "Restablecer", "save": "Guardar", "scann_code": "QR Code Scanner - Escanea el código QR de tu pareja", @@ -219,6 +222,7 @@ "email": "Te hemos enviado un correo electrónico.", "errorTitle": "Atención!", "register": "Ya estás registrado, por favor revisa tu correo electrónico y haz clic en el enlace de activación.", + "reply": "Gracias, tu respuesta ha sido enviada.", "reset": "Tu contraseña ha sido cambiada.", "title": "Gracias!", "unsetPassword": "Tu contraseña aún no ha sido configurada. Por favor reinícialo." @@ -250,8 +254,8 @@ "de": "Deutsch", "en": "English", "es": "Español", - "fr": "Francés", - "nl": "Holandés", + "fr": "Français", + "nl": "Nederlands", "success": "Tu idioma ha sido cambiado con éxito." }, "name": { diff --git a/frontend/src/locales/fr.json b/frontend/src/locales/fr.json index 44a08cd82..61037af1a 100644 --- a/frontend/src/locales/fr.json +++ b/frontend/src/locales/fr.json @@ -22,6 +22,7 @@ "continue-to-registration": "Continuez l´inscription", "current-community": "Communauté actuelle", "members": "Membres", + "moderator": "Modérateur", "moderators": "Modérateurs", "myContributions": "Mes contributions aux biens communs", "openContributionLinks": "liste de liens de contribution publique", @@ -34,10 +35,11 @@ "contribution": { "activity": "Activité", "alert": { + "answerQuestion": "S'il te plais répond à la question", "communityNoteList": "Vous trouverez ci-contre toutes les contributions versées et certifiées de tous les membres de cette communauté.", "confirm": " Approuvé", + "in_progress": "Il y a une question du modérateur.", "myContributionNoteList": "À tout moment vous pouvez éditer ou supprimer les données qui n´ont pas été confirmées.", - "myContributionNoteSupport": "Vous aurez bientôt la possibilité de dialoguer avec un médiateur. Si vous rencontrez un problème maintenant, merci de contacter l´aide en ligne.", "pending": "Inscription en attente de validation", "rejected": "supprimé" }, @@ -130,6 +132,7 @@ "password_new_repeat": "Répétez le nouveau mot de passe", "password_old": "Ancien mot de passe", "recipient": "Destinataire", + "reply": "Répondre", "reset": "Réinitialiser", "save": "Sauvegarder", "scann_code": "QR Code Scanner - Scannez le QR code de votre partenaire", @@ -219,6 +222,7 @@ "email": "Nous vous avons envoyé un email.", "errorTitle": "Attention!", "register": "Vous êtes enregistré maintenant, merci de vérifier votre boîte mail et cliquer sur le lien d´activation.", + "reply": "Merci, ta réponse a été envoyée.", "reset": "Votre mot de passe a été modifié.", "title": "Merci!", "unsetPassword": "Votre mot de passe n´a pas été accepté. Merci de le réinitialiser." @@ -247,11 +251,11 @@ "settings": { "language": { "changeLanguage": "Changer la langue", - "de": "Allemand", - "en": "Anglais", - "es": "Espagnol", + "de": "Deutsch", + "en": "English", + "es": "Español", "fr": "Français", - "nl": "Néerlandais", + "nl": "Nederlands", "success": "Votre langue de préférence a bien été actualisée." }, "name": { diff --git a/frontend/src/locales/index.js b/frontend/src/locales/index.js index aa27a2e32..eed77ec2a 100644 --- a/frontend/src/locales/index.js +++ b/frontend/src/locales/index.js @@ -24,7 +24,7 @@ const locales = [ enabled: true, }, { - name: 'Holandés', + name: 'Nederlands', code: 'nl', iso: 'nl-NL', enabled: true, diff --git a/frontend/src/locales/nl.json b/frontend/src/locales/nl.json index f817d1458..99b972514 100644 --- a/frontend/src/locales/nl.json +++ b/frontend/src/locales/nl.json @@ -22,6 +22,7 @@ "continue-to-registration": "Verder ter registratie", "current-community": "Actuele gemeenschap", "members": "Leden", + "moderator": "Moderator", "moderators": "Moderators", "myContributions": "Mijn bijdragen voor het algemeen belang", "openContributionLinks": "openbare lijst van bijdragen", @@ -34,10 +35,11 @@ "contribution": { "activity": "Activiteit", "alert": { + "answerQuestion": "Please answer the question", "communityNoteList": "Hier vind je alle ingediende en bevestigde bijdragen van alle leden uit deze gemeenschap.", "confirm": "bevestigt", + "in_progress": "There is a question from the moderators.", "myContributionNoteList": "Ingediende bijdragen, die nog niet bevestigd zijn, kun je op elk moment wijzigen of verwijderen.", - "myContributionNoteSupport": "Hier heb je binnenkort de mogelijkheid een gesprek met een moderator te voeren. Mocht je nu problemen hebben, dan neem alsjeblieft contact op met Support.", "pending": "Ingediend en wacht op bevestiging", "rejected": "afgewezen" }, @@ -130,6 +132,7 @@ "password_new_repeat": "Nieuw wachtwoord herhalen", "password_old": "Oud wachtwoord", "recipient": "Ontvanger", + "reply": "Antwoord", "reset": "Resetten", "save": "Opslaan", "scann_code": "QR Code Scanner - Scan de QR Code van uw partner", @@ -219,6 +222,7 @@ "email": "We hebben jou een email gestuurd.", "errorTitle": "Opgelet!", "register": "Je bent nu geregistreerd. Controleer alsjeblieft je emails en klik op de activeringslink.", + "reply": "Dank u, uw antwoord is verzonden.", "reset": "Jouw wachtwoord werd gewijzigd.", "title": "Dankjewel!", "unsetPassword": "Jouw wachtwoord werd nog niet ingesteld. Doe het alsjeblieft opnieuw." @@ -247,10 +251,10 @@ "settings": { "language": { "changeLanguage": "Taal veranderen", - "de": "Duits", - "en": "Engels", - "es": "Spaans", - "fr": "Frans", + "de": "Deutsch", + "en": "English", + "es": "Español", + "fr": "Français", "nl": "Nederlands", "success": "Jouw taal werd succesvol veranderd." }, diff --git a/frontend/src/pages/Community.spec.js b/frontend/src/pages/Community.spec.js index b4aa43785..26d30c1d9 100644 --- a/frontend/src/pages/Community.spec.js +++ b/frontend/src/pages/Community.spec.js @@ -93,9 +93,7 @@ describe('Community', () => { expect(wrapper.findAll('div[role="tabpanel"]')).toHaveLength(3) }) - it('has first tab active by default', () => { - expect(wrapper.findAll('div[role="tabpanel"]').at(0).classes('active')).toBe(true) - }) + it.todo('check for correct tabIndex if state is "IN_PROGRESS" or not') }) describe('API calls after creation', () => { diff --git a/frontend/src/pages/Community.vue b/frontend/src/pages/Community.vue index 64aca6156..8906f40e7 100644 --- a/frontend/src/pages/Community.vue +++ b/frontend/src/pages/Community.vue @@ -2,7 +2,7 @@
- + {{ $t('contribution.alert.pending') }} +
  • + + {{ $t('contribution.alert.in_progress') }} +
  • {{ $t('contribution.alert.confirm') }} @@ -32,9 +36,6 @@

  • -

    - {{ $t('contribution.alert.myContributionNoteSupport') }} -

    item.state === 'IN_PROGRESS')) { + this.tabIndex = 1 + } else { + this.tabIndex = 0 + } }) .catch((err) => { this.toastError(err.message) @@ -258,6 +265,9 @@ export default { updateTransactions(pagination) { this.$emit('update-transactions', pagination) }, + updateState(id) { + this.items.find((item) => item.id === id).state = 'PENDING' + }, }, created() { // verifyLogin is important at this point so that creation is updated on reload if they are deleted in a session in the admin area. @@ -271,6 +281,7 @@ export default { pageSize: this.pageSize, }) this.updateTransactions(0) + this.tabIndex = 1 }, } diff --git a/frontend/src/pages/InfoStatistic.spec.js b/frontend/src/pages/InfoStatistic.spec.js index b7b7b4a5c..e6475ed41 100644 --- a/frontend/src/pages/InfoStatistic.spec.js +++ b/frontend/src/pages/InfoStatistic.spec.js @@ -98,7 +98,7 @@ describe('InfoStatistic', () => { ) }) - it('calls getCommunityStatistics', () => { + it.skip('calls getCommunityStatistics', () => { expect(apolloQueryMock).toBeCalledWith( expect.objectContaining({ query: communityStatistics, @@ -115,12 +115,12 @@ describe('InfoStatistic', () => { wrapper = Wrapper() }) - it('toasts three error messages', () => { + it('toasts two error messages', () => { expect(toastErrorSpy).toBeCalledWith( 'listContributionLinks has no result, use default data', ) expect(toastErrorSpy).toBeCalledWith('searchAdminUsers has no result, use default data') - expect(toastErrorSpy).toBeCalledWith('communityStatistics has no result, use default data') + // expect(toastErrorSpy).toBeCalledWith('communityStatistics has no result, use default data') }) }) }) diff --git a/frontend/src/pages/InfoStatistic.vue b/frontend/src/pages/InfoStatistic.vue index 481e34dd6..309404f48 100644 --- a/frontend/src/pages/InfoStatistic.vue +++ b/frontend/src/pages/InfoStatistic.vue @@ -43,6 +43,7 @@ {{ supportMail }} +