diff --git a/backend/src/graphql/arg/UpdateUserInfosArgs.ts b/backend/src/graphql/arg/UpdateUserInfosArgs.ts index 0920fb3bc..a6c80cddd 100644 --- a/backend/src/graphql/arg/UpdateUserInfosArgs.ts +++ b/backend/src/graphql/arg/UpdateUserInfosArgs.ts @@ -1,6 +1,8 @@ -import { IsBoolean, IsInt, IsString } from 'class-validator' +import { IsBoolean, IsEnum, IsInt, IsString } from 'class-validator' import { ArgsType, Field, InputType, Int } from 'type-graphql' +import { GmsPublishLocationType } from '@enum/GmsPublishLocationType' +import { GmsPublishNameType } from '@enum/GmsPublishNameType' import { Location } from '@model/Location' import { isValidLocation } from '@/graphql/validator/Location' @@ -44,19 +46,19 @@ export class UpdateUserInfosArgs { @IsBoolean() hideAmountGDT?: boolean - @Field({ nullable: true, defaultValue: true }) + @Field({ nullable: true }) @IsBoolean() gmsAllowed?: boolean - @Field(() => Int, { nullable: true, defaultValue: 0 }) - @IsInt() - gmsPublishName?: number | null + @Field(() => GmsPublishNameType, { nullable: true }) + @IsEnum(GmsPublishNameType) + gmsPublishName?: GmsPublishNameType | null @Field(() => Location, { nullable: true }) @isValidLocation() gmsLocation?: Location | null - @Field(() => Int, { nullable: true, defaultValue: 2 }) - @IsInt() - gmsPublishLocation?: number | null + @Field(() => GmsPublishLocationType, { nullable: true }) + @IsEnum(GmsPublishLocationType) + gmsPublishLocation?: GmsPublishLocationType | null } diff --git a/backend/src/graphql/model/User.ts b/backend/src/graphql/model/User.ts index d24a717c4..166367fd1 100644 --- a/backend/src/graphql/model/User.ts +++ b/backend/src/graphql/model/User.ts @@ -1,6 +1,9 @@ import { User as dbUser } from '@entity/User' import { ObjectType, Field, Int } from 'type-graphql' +import { GmsPublishLocationType } from '@enum/GmsPublishLocationType' +import { GmsPublishNameType } from '@enum/GmsPublishNameType' + import { KlickTipp } from './KlickTipp' @ObjectType() @@ -29,6 +32,9 @@ export class User { this.hasElopage = null this.hideAmountGDD = user.hideAmountGDD this.hideAmountGDT = user.hideAmountGDT + this.gmsAllowed = user.gmsAllowed + this.gmsPublishName = user.gmsPublishName + this.gmsPublishLocation = user.gmsPublishLocation } } @@ -74,6 +80,15 @@ export class User { @Field(() => Boolean) hideAmountGDT: boolean + @Field(() => Boolean) + gmsAllowed: boolean + + @Field(() => GmsPublishNameType, { nullable: true }) + gmsPublishName: GmsPublishNameType | null + + @Field(() => GmsPublishLocationType, { nullable: true }) + gmsPublishLocation: GmsPublishLocationType | null + // This is not the users publisherId, but the one of the users who recommend him @Field(() => Int, { nullable: true }) publisherId: number | null diff --git a/backend/src/graphql/resolver/TransactionResolver.test.ts b/backend/src/graphql/resolver/TransactionResolver.test.ts index 1bb4a86f7..97e210dfa 100644 --- a/backend/src/graphql/resolver/TransactionResolver.test.ts +++ b/backend/src/graphql/resolver/TransactionResolver.test.ts @@ -15,8 +15,6 @@ import { ApolloServerTestClient } from 'apollo-server-testing' import { GraphQLError } from 'graphql' import { v4 as uuidv4 } from 'uuid' -import { GmsPublishLocationType } from '@enum/GmsPublishLocationType' -import { GmsPublishNameType } from '@enum/GmsPublishNameType' import { cleanDB, testEnvironment } from '@test/helpers' import { logger } from '@test/testSetup' @@ -534,9 +532,6 @@ describe('send coins', () => { mutation: updateUserInfos, variables: { alias: 'bob', - gmsAllowed: true, - gmsPublishName: GmsPublishNameType.GMS_PUBLISH_NAME_ALIAS_OR_INITALS, - gmsPublishLocation: GmsPublishLocationType.GMS_LOCATION_TYPE_RANDOM, }, }) await mutate({ diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index c570dbd9f..430aad2f5 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -1303,8 +1303,10 @@ describe('UserResolver', () => { mutation: updateUserInfos, variables: { gmsAllowed: false, - gmsPublishName: GmsPublishNameType.GMS_PUBLISH_NAME_FIRST_INITIAL, - gmsPublishLocation: GmsPublishLocationType.GMS_LOCATION_TYPE_APPROXIMATE, + gmsPublishName: + GmsPublishNameType[GmsPublishNameType.GMS_PUBLISH_NAME_FIRST_INITIAL], + gmsPublishLocation: + GmsPublishLocationType[GmsPublishLocationType.GMS_LOCATION_TYPE_APPROXIMATE], }, }) await expect(User.find()).resolves.toEqual([ @@ -1326,9 +1328,11 @@ describe('UserResolver', () => { mutation: updateUserInfos, variables: { gmsAllowed: true, - gmsPublishName: GmsPublishNameType.GMS_PUBLISH_NAME_ALIAS_OR_INITALS, + gmsPublishName: + GmsPublishNameType[GmsPublishNameType.GMS_PUBLISH_NAME_ALIAS_OR_INITALS], gmsLocation: loc, - gmsPublishLocation: GmsPublishLocationType.GMS_LOCATION_TYPE_RANDOM, + gmsPublishLocation: + GmsPublishLocationType[GmsPublishLocationType.GMS_LOCATION_TYPE_RANDOM], }, }) await expect(User.find()).resolves.toEqual([ @@ -2674,9 +2678,6 @@ describe('UserResolver', () => { mutation: updateUserInfos, variables: { alias: 'bibi', - gmsAllowed: true, - gmsPublishName: GmsPublishNameType.GMS_PUBLISH_NAME_ALIAS_OR_INITALS, - gmsPublishLocation: GmsPublishLocationType.GMS_LOCATION_TYPE_RANDOM, }, }) }) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 3f70ce112..d980dabed 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -19,8 +19,6 @@ import { SearchUsersFilters } from '@arg/SearchUsersFilters' import { SetUserRoleArgs } from '@arg/SetUserRoleArgs' import { UnsecureLoginArgs } from '@arg/UnsecureLoginArgs' import { UpdateUserInfosArgs } from '@arg/UpdateUserInfosArgs' -import { GmsPublishLocationType } from '@enum/GmsPublishLocationType' -import { GmsPublishNameType } from '@enum/GmsPublishNameType' import { OptInType } from '@enum/OptInType' import { Order } from '@enum/Order' import { PasswordEncryptionType } from '@enum/PasswordEncryptionType' @@ -561,17 +559,6 @@ export class UserResolver { logger.info( `updateUserInfos(${firstName}, ${lastName}, ${alias}, ${language}, ***, ***, ${hideAmountGDD}, ${hideAmountGDT}, ${gmsAllowed}, ${gmsPublishName}, ${gmsLocation}, ${gmsPublishLocation})...`, ) - // check default arg settings - if (gmsAllowed === null || gmsAllowed === undefined) { - gmsAllowed = true - } - if (!gmsPublishName) { - gmsPublishName = GmsPublishNameType.GMS_PUBLISH_NAME_ALIAS_OR_INITALS - } - if (!gmsPublishLocation) { - gmsPublishLocation = GmsPublishLocationType.GMS_LOCATION_TYPE_RANDOM - } - const user = getUser(context) // try { if (firstName) { @@ -619,13 +606,18 @@ export class UserResolver { if (hideAmountGDT !== undefined) { user.hideAmountGDT = hideAmountGDT } - - user.gmsAllowed = gmsAllowed - user.gmsPublishName = gmsPublishName + if (gmsAllowed !== undefined) { + user.gmsAllowed = gmsAllowed + } + if (gmsPublishName !== null && gmsPublishName !== undefined) { + user.gmsPublishName = gmsPublishName + } if (gmsLocation) { user.location = Location2Point(gmsLocation) } - user.gmsPublishLocation = gmsPublishLocation + if (gmsPublishLocation !== null && gmsPublishLocation !== undefined) { + user.gmsPublishLocation = gmsPublishLocation + } // } catch (err) { // console.log('error:', err) // } diff --git a/backend/src/seeds/graphql/mutations.ts b/backend/src/seeds/graphql/mutations.ts index b10bb4b4e..22c402e65 100644 --- a/backend/src/seeds/graphql/mutations.ts +++ b/backend/src/seeds/graphql/mutations.ts @@ -35,9 +35,9 @@ export const updateUserInfos = gql` $hideAmountGDD: Boolean $hideAmountGDT: Boolean $gmsAllowed: Boolean - $gmsPublishName: Int + $gmsPublishName: GmsPublishNameType $gmsLocation: Location - $gmsPublishLocation: Int + $gmsPublishLocation: GmsPublishLocationType ) { updateUserInfos( firstName: $firstName diff --git a/deployment/bare_metal/.env.dist b/deployment/bare_metal/.env.dist index 9e6e911eb..ed6cbb0b4 100644 --- a/deployment/bare_metal/.env.dist +++ b/deployment/bare_metal/.env.dist @@ -26,7 +26,7 @@ EMAIL_CODE_REQUEST_TIME=10 # config versions DATABASE_CONFIG_VERSION=v1.2022-03-18 BACKEND_CONFIG_VERSION=v21.2024-01-06 -FRONTEND_CONFIG_VERSION=v5.2024-01-08 +FRONTEND_CONFIG_VERSION=v6.2024-02-27 ADMIN_CONFIG_VERSION=v2.2024-01-04 FEDERATION_CONFIG_VERSION=v2.2023-08-24 FEDERATION_DHT_CONFIG_VERSION=v4.2024-01-17 diff --git a/frontend/.env.dist b/frontend/.env.dist index f7e7edcd6..f680d9a50 100644 --- a/frontend/.env.dist +++ b/frontend/.env.dist @@ -21,3 +21,5 @@ META_DESCRIPTION_EN="Gratitude is the currency of the new age. More and more peo META_KEYWORDS_DE="Grundeinkommen, Währung, Dankbarkeit, Schenk-Ökonomie, Natürliche Ökonomie des Lebens, Ökonomie, Ökologie, Potenzialentfaltung, Schenken und Danken, Kreislauf des Lebens, Geldsystem" META_KEYWORDS_EN="Basic Income, Currency, Gratitude, Gift Economy, Natural Economy of Life, Economy, Ecology, Potential Development, Giving and Thanking, Cycle of Life, Monetary System" META_AUTHOR="Bernd Hückstädt - Gradido-Akademie" + +GMS_ACTIVE=false diff --git a/frontend/.env.template b/frontend/.env.template index c365ab8cf..c121545da 100644 --- a/frontend/.env.template +++ b/frontend/.env.template @@ -24,3 +24,5 @@ META_DESCRIPTION_EN=$META_DESCRIPTION_EN META_KEYWORDS_DE=$META_KEYWORDS_DE META_KEYWORDS_EN=$META_KEYWORDS_EN META_AUTHOR=$META_AUTHOR + +GMS_ACTIVE=$GMS_ACTIVE \ No newline at end of file diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 46f7dacb8..663c9e7d4 100755 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -71,4 +71,16 @@ export default { .text-color-gdd-yellow { color: rgb(197 141 56); } + +.dropdown > .dropdown-toggle { + border-radius: 17px; + height: 50px; + text-align: left; +} +.dropdown-toggle::after { + float: right; + top: 50%; + transform: translateY(-50%); + position: relative; +} diff --git a/frontend/src/components/CommunitySwitch.vue b/frontend/src/components/CommunitySwitch.vue index ac9ce3182..4ff3d9781 100644 --- a/frontend/src/components/CommunitySwitch.vue +++ b/frontend/src/components/CommunitySwitch.vue @@ -90,20 +90,3 @@ export default { }, } - diff --git a/frontend/src/components/UserSettings/UserGMSLocation.vue b/frontend/src/components/UserSettings/UserGMSLocation.vue new file mode 100644 index 000000000..0d7fe9ab7 --- /dev/null +++ b/frontend/src/components/UserSettings/UserGMSLocation.vue @@ -0,0 +1,8 @@ + + diff --git a/frontend/src/components/UserSettings/UserGMSLocationFormat.spec.js b/frontend/src/components/UserSettings/UserGMSLocationFormat.spec.js new file mode 100644 index 000000000..9ec235d95 --- /dev/null +++ b/frontend/src/components/UserSettings/UserGMSLocationFormat.spec.js @@ -0,0 +1,79 @@ +import { mount } from '@vue/test-utils' +import UserGMSLocationFormat from './UserGMSLocationFormat.vue' +import { toastErrorSpy } from '@test/testSetup' + +const mockAPIcall = jest.fn() + +const storeCommitMock = jest.fn() + +const localVue = global.localVue + +describe('UserGMSLocationFormat', () => { + let wrapper + beforeEach(() => { + wrapper = mount(UserGMSLocationFormat, { + mocks: { + $t: (key) => key, // Mocking the translation function + $store: { + state: { + gmsPublishLocation: null, + }, + commit: storeCommitMock, + }, + $apollo: { + mutate: mockAPIcall, + }, + }, + localVue, + propsData: { + selectedOption: 'GMS_LOCATION_TYPE_RANDOM', + }, + }) + }) + + afterEach(() => { + wrapper.destroy() + }) + + it('renders the correct dropdown options', () => { + const dropdownItems = wrapper.findAll('.dropdown-item') + expect(dropdownItems.length).toBe(3) + + const labels = dropdownItems.wrappers.map((item) => item.text()) + expect(labels).toEqual([ + 'settings.GMS.publish-location.exact', + 'settings.GMS.publish-location.approximate', + 'settings.GMS.publish-location.random', + ]) + }) + + it('updates selected option on click', async () => { + const dropdownItem = wrapper.findAll('.dropdown-item').at(1) // Click the second item + await dropdownItem.trigger('click') + + expect(wrapper.emitted().gmsPublishLocation).toBeTruthy() + expect(wrapper.emitted().gmsPublishLocation.length).toBe(1) + expect(wrapper.emitted().gmsPublishLocation[0]).toEqual(['GMS_LOCATION_TYPE_APPROXIMATE']) + }) + + it('does not update when clicking on already selected option', async () => { + const dropdownItem = wrapper.findAll('.dropdown-item').at(2) // Click the third item (which is already selected) + await dropdownItem.trigger('click') + + expect(wrapper.emitted().gmsPublishLocation).toBeFalsy() + }) + + describe('update with error', () => { + beforeEach(async () => { + mockAPIcall.mockRejectedValue({ + message: 'Ouch', + }) + const dropdownItem = wrapper.findAll('.dropdown-item').at(1) // Click the second item + await dropdownItem.trigger('click') + }) + + it('toasts an error message', () => { + expect(toastErrorSpy).toBeCalledWith('Ouch') + }) + }) +}) diff --git a/frontend/src/components/UserSettings/UserGMSLocationFormat.vue b/frontend/src/components/UserSettings/UserGMSLocationFormat.vue new file mode 100644 index 000000000..d20135d5e --- /dev/null +++ b/frontend/src/components/UserSettings/UserGMSLocationFormat.vue @@ -0,0 +1,73 @@ + + + diff --git a/frontend/src/components/UserSettings/UserGMSNamingFormat.spec.js b/frontend/src/components/UserSettings/UserGMSNamingFormat.spec.js new file mode 100644 index 000000000..3dbbfdb2c --- /dev/null +++ b/frontend/src/components/UserSettings/UserGMSNamingFormat.spec.js @@ -0,0 +1,81 @@ +import { mount } from '@vue/test-utils' +import UserGMSNamingFormat from './UserGMSNamingFormat.vue' +import { toastErrorSpy } from '@test/testSetup' + +const mockAPIcall = jest.fn() + +const storeCommitMock = jest.fn() + +const localVue = global.localVue + +describe('UserGMSNamingFormat', () => { + let wrapper + beforeEach(() => { + wrapper = mount(UserGMSNamingFormat, { + mocks: { + $t: (key) => key, // Mocking the translation function + $store: { + state: { + gmsPublishName: null, + }, + commit: storeCommitMock, + }, + $apollo: { + mutate: mockAPIcall, + }, + }, + localVue, + propsData: { + selectedOption: 'GMS_PUBLISH_NAME_ALIAS_OR_INITALS', + }, + }) + }) + + afterEach(() => { + wrapper.destroy() + }) + + it('renders the correct dropdown options', () => { + const dropdownItems = wrapper.findAll('.dropdown-item') + expect(dropdownItems.length).toBe(5) + + const labels = dropdownItems.wrappers.map((item) => item.text()) + expect(labels).toEqual([ + 'settings.GMS.publish-name.alias-or-initials', + 'settings.GMS.publish-name.initials', + 'settings.GMS.publish-name.first', + 'settings.GMS.publish-name.first-initial', + 'settings.GMS.publish-name.name-full', + ]) + }) + + it('updates selected option on click', async () => { + const dropdownItem = wrapper.findAll('.dropdown-item').at(3) // Click the fourth item + await dropdownItem.trigger('click') + + expect(wrapper.emitted().gmsPublishName).toBeTruthy() + expect(wrapper.emitted().gmsPublishName.length).toBe(1) + expect(wrapper.emitted().gmsPublishName[0]).toEqual(['GMS_PUBLISH_NAME_FIRST_INITIAL']) + }) + + it('does not update when clicking on already selected option', async () => { + const dropdownItem = wrapper.findAll('.dropdown-item').at(0) // Click the first item (which is already selected) + await dropdownItem.trigger('click') + + expect(wrapper.emitted().gmsPublishName).toBeFalsy() + }) + + describe('update with error', () => { + beforeEach(async () => { + mockAPIcall.mockRejectedValue({ + message: 'Ouch', + }) + const dropdownItem = wrapper.findAll('.dropdown-item').at(2) // Click the third item + await dropdownItem.trigger('click') + }) + + it('toasts an error message', () => { + expect(toastErrorSpy).toBeCalledWith('Ouch') + }) + }) +}) diff --git a/frontend/src/components/UserSettings/UserGMSNamingFormat.vue b/frontend/src/components/UserSettings/UserGMSNamingFormat.vue new file mode 100644 index 000000000..29b4cd384 --- /dev/null +++ b/frontend/src/components/UserSettings/UserGMSNamingFormat.vue @@ -0,0 +1,87 @@ + + + diff --git a/frontend/src/components/UserSettings/UserGMSSwitch.vue b/frontend/src/components/UserSettings/UserGMSSwitch.vue new file mode 100644 index 000000000..355beeff2 --- /dev/null +++ b/frontend/src/components/UserSettings/UserGMSSwitch.vue @@ -0,0 +1,45 @@ + + diff --git a/frontend/src/config/index.js b/frontend/src/config/index.js index dd2e85dac..1ead8ecf0 100644 --- a/frontend/src/config/index.js +++ b/frontend/src/config/index.js @@ -8,7 +8,7 @@ const constants = { DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0 CONFIG_VERSION: { DEFAULT: 'DEFAULT', - EXPECTED: 'v5.2024-01-08', + EXPECTED: 'v6.2024-02-27', CURRENT: '', }, } @@ -20,6 +20,10 @@ const version = { BUILD_COMMIT_SHORT: (process.env.BUILD_COMMIT ?? '0000000').slice(0, 7), } +const features = { + GMS_ACTIVE: process.env.GMS_ACTIVE ?? false, +} + const environment = { NODE_ENV: process.env.NODE_ENV, DEBUG: process.env.NODE_ENV !== 'production' ?? false, @@ -81,6 +85,7 @@ if ( const CONFIG = { ...constants, ...version, + ...features, ...environment, ...endpoints, ...community, diff --git a/frontend/src/graphql/mutations.js b/frontend/src/graphql/mutations.js index cade098da..8d28bbff6 100644 --- a/frontend/src/graphql/mutations.js +++ b/frontend/src/graphql/mutations.js @@ -35,9 +35,9 @@ export const updateUserInfos = gql` $hideAmountGDD: Boolean $hideAmountGDT: Boolean $gmsAllowed: Boolean - $gmsPublishName: Int + $gmsPublishName: GmsPublishNameType $gmsLocation: Location - $gmsPublishLocation: Int + $gmsPublishLocation: GmsPublishLocationType ) { updateUserInfos( firstName: $firstName @@ -172,6 +172,9 @@ export const login = gql` klickTipp { newsletterState } + gmsAllowed + gmsPublishName + gmsPublishLocation hasElopage publisherId roles diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index 337722940..1c37d5e24 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -5,8 +5,10 @@ "1000thanks": "1000 Dank, weil du bei uns bist!", "125": "125%", "85": "85%", + "ExternServices": "Verknüpfte Dienste", "GDD": "GDD", "GDT": "GDT", + "GMS": "Gradido Karte", "PersonalDetails": "Persönliche Angaben", "advanced-calculation": "Vorausberechnung", "asterisks": "****", @@ -290,6 +292,36 @@ }, "settings": { "emailInfo": "Kann aktuell noch nicht geändert werden.", + "GMS": { + "disabled": "Daten werden nicht nach GMS exportiert", + "enabled": "Daten werden nach GMS exportiert", + "location": { + "label": "Positionsbestimmung", + "button": "Klick mich!" + }, + "location-format": "Positionstyp", + "naming-format": "Namensformat im GMS", + "publish-location": { + "exact": "Genaue Position", + "approximate": "Ungefähre Position", + "random": "Zufallsposition", + "updated": "Positionstyp für GMS aktualisiert" + }, + "publish-name": { + "alias-or-initials": "Benutzername oder Initialen", + "alias-or-initials-tooltip": "Benutzername, falls vorhanden, oder die Initialen von Vorname und Nachname", + "first": "Vorname", + "first-tooltip": "Nur der Vornamen", + "first-initial": "Vorname und Initiale", + "first-initial-tooltip": "Vornamen plus Anfangsbuchstabe des Nachnamens", + "initials": "Initialen", + "initials-tooltip": "Initialen von Vor- und Nachname unabhängig von der Existenz des Benutzernamens", + "name-full": "Ganzer Name", + "name-full-tooltip": "Vollständiger Name: Vorname plus Nachname", + "updated": "Namensformat für GMS aktualisiert" + }, + "switch": "Erlaubnis Daten nach GMS zu exportieren." + }, "hideAmountGDD": "Dein GDD Betrag ist versteckt.", "hideAmountGDT": "Dein GDT Betrag ist versteckt.", "info": "Transaktionen können nun per Benutzername oder E-Mail-Adresse getätigt werden.", diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 982d22159..7c607ecbb 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -5,8 +5,10 @@ "1000thanks": "1000 thanks for being with us!", "125": "125%", "85": "85%", + "ExternServices": "Extern Services", "GDD": "GDD", "GDT": "GDT", + "GMS": "Gradido Map", "PersonalDetails": "Personal details", "advanced-calculation": "Advanced calculation", "asterisks": "****", @@ -290,6 +292,36 @@ }, "settings": { "emailInfo": "Cannot be changed at this time.", + "GMS": { + "disabled": "Data not exported to GMS", + "enabled": "Data exported to GMS", + "location": { + "label": "pinpoint location", + "button": "click me!" + }, + "location-format": "location type", + "naming-format": "Format of name in GMS", + "publish-location": { + "exact": "exact position", + "approximate": "approximate position", + "random": "random position", + "updated": "format of location for GMS updated" + }, + "publish-name": { + "alias-or-initials": "Username or initials", + "alias-or-initials-tooltip": "username if exists or Initials of firstname and lastname", + "first": "firstname", + "first-tooltip": "the firstname only", + "first-initial": "firstname and initial", + "first-initial-tooltip": "firstname plus initial of lastname", + "initials": "Initials of firstname and lastname independent if username exists", + "initials-tooltip": "Initials of firstname and lastname independent if username exists", + "name-full": "fullname", + "name-full-tooltip": "fullname: firstname plus lastname", + "updated": "format of name for GMS updated" + }, + "switch": "Allow data export to GMS" + }, "hideAmountGDD": "Your GDD amount is hidden.", "hideAmountGDT": "Your GDT amount is hidden.", "info": "Transactions can now be made by username or email address.", diff --git a/frontend/src/pages/Settings.vue b/frontend/src/pages/Settings.vue index 1530e5e97..c74af6679 100644 --- a/frontend/src/pages/Settings.vue +++ b/frontend/src/pages/Settings.vue @@ -1,81 +1,129 @@