Merge pull request #3309 from gradido/humhub_options

feat(frontend): add humhub switch and name format
This commit is contained in:
einhornimmond 2024-04-19 11:26:19 +02:00 committed by GitHub
commit 302fd037e7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 744 additions and 118 deletions

View File

@ -12,7 +12,7 @@ Decimal.set({
})
const constants = {
DB_VERSION: '0083-join_community_federated_communities',
DB_VERSION: '0084-introduce_humhub_registration',
DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0
LOG4JS_CONFIG: 'log4js-config.json',
// default log level on production should be info

View File

@ -3,6 +3,7 @@ import { ArgsType, Field, InputType, Int } from 'type-graphql'
import { GmsPublishLocationType } from '@enum/GmsPublishLocationType'
import { GmsPublishNameType } from '@enum/GmsPublishNameType'
import { PublishNameType } from '@enum/PublishNameType'
import { Location } from '@model/Location'
import { isValidLocation } from '@/graphql/validator/Location'
@ -46,6 +47,10 @@ export class UpdateUserInfosArgs {
@IsBoolean()
hideAmountGDT?: boolean
@Field({ nullable: true })
@IsBoolean()
humhubAllowed?: boolean
@Field({ nullable: true })
@IsBoolean()
gmsAllowed?: boolean
@ -54,6 +59,10 @@ export class UpdateUserInfosArgs {
@IsEnum(GmsPublishNameType)
gmsPublishName?: GmsPublishNameType | null
@Field(() => PublishNameType, { nullable: true })
@IsEnum(PublishNameType)
humhubPublishName?: PublishNameType | null
@Field(() => Location, { nullable: true })
@isValidLocation()
gmsLocation?: Location | null

View File

@ -0,0 +1,19 @@
import { registerEnumType } from 'type-graphql'
/**
* Enum for decide which parts from first- and last-name are allowed to be published in an extern service
*/
export enum PublishNameType {
PUBLISH_NAME_NONE = 0,
PUBLISH_NAME_INITIALS = 1,
PUBLISH_NAME_FIRST = 2,
PUBLISH_NAME_FIRST_INITIAL = 3,
PUBLISH_NAME_LAST = 4,
PUBLISH_NAME_INITIAL_LAST = 5,
PUBLISH_NAME_FULL = 6,
}
registerEnumType(PublishNameType, {
name: 'PublishNameType', // this one is mandatory
description: 'Type of first- and last-name publishing for extern service', // this one is optional
})

View File

@ -3,6 +3,7 @@ import { ObjectType, Field, Int } from 'type-graphql'
import { GmsPublishLocationType } from '@enum/GmsPublishLocationType'
import { GmsPublishNameType } from '@enum/GmsPublishNameType'
import { PublishNameType } from '@enum/PublishNameType'
import { KlickTipp } from './KlickTipp'
@ -32,8 +33,10 @@ export class User {
this.hasElopage = null
this.hideAmountGDD = user.hideAmountGDD
this.hideAmountGDT = user.hideAmountGDT
this.humhubAllowed = user.humhubAllowed
this.gmsAllowed = user.gmsAllowed
this.gmsPublishName = user.gmsPublishName
this.humhubPublishName = user.humhubPublishName
this.gmsPublishLocation = user.gmsPublishLocation
}
}
@ -80,12 +83,18 @@ export class User {
@Field(() => Boolean)
hideAmountGDT: boolean
@Field(() => Boolean)
humhubAllowed: boolean
@Field(() => Boolean)
gmsAllowed: boolean
@Field(() => GmsPublishNameType, { nullable: true })
gmsPublishName: GmsPublishNameType | null
@Field(() => PublishNameType, { nullable: true })
humhubPublishName: PublishNameType | null
@Field(() => GmsPublishLocationType, { nullable: true })
gmsPublishLocation: GmsPublishLocationType | null

View File

@ -183,7 +183,9 @@ describe('UserResolver', () => {
communityUuid: homeCom.communityUuid,
foreign: false,
gmsAllowed: true,
humhubAllowed: false,
gmsPublishName: 0,
humhubPublishName: 0,
gmsPublishLocation: 2,
location: null,
gmsRegistered: false,

View File

@ -394,8 +394,8 @@ export class UserResolver {
logger.addContext('user', 'unknown')
logger.info(`forgotPassword(${email})...`)
email = email.trim().toLowerCase()
const user = await findUserByEmail(email).catch(() => {
logger.warn(`fail on find UserContact per ${email}`)
const user = await findUserByEmail(email).catch((error) => {
logger.warn(`fail on find UserContact per ${email} because: ${error}`)
})
if (!user || user.deletedAt) {
@ -559,8 +559,10 @@ export class UserResolver {
passwordNew,
hideAmountGDD,
hideAmountGDT,
humhubAllowed,
gmsAllowed,
gmsPublishName,
humhubPublishName,
gmsLocation,
gmsPublishLocation,
} = updateUserInfosArgs
@ -617,12 +619,18 @@ export class UserResolver {
if (hideAmountGDT !== undefined) {
user.hideAmountGDT = hideAmountGDT
}
if (humhubAllowed !== undefined) {
user.humhubAllowed = humhubAllowed
}
if (gmsAllowed !== undefined) {
user.gmsAllowed = gmsAllowed
}
if (gmsPublishName !== null && gmsPublishName !== undefined) {
user.gmsPublishName = gmsPublishName
}
if (humhubPublishName !== null && humhubPublishName !== undefined) {
user.humhubPublishName = humhubPublishName
}
if (gmsLocation) {
user.location = Location2Point(gmsLocation)
}

View File

@ -52,7 +52,9 @@ const communityDbUser: dbUser = {
communityUuid: '55555555-4444-4333-2222-11111111',
community: null,
gmsPublishName: 0,
humhubPublishName: 0,
gmsAllowed: false,
humhubAllowed: false,
location: null,
gmsPublishLocation: 2,
gmsRegistered: false,

View File

@ -0,0 +1,176 @@
import {
BaseEntity,
Entity,
PrimaryGeneratedColumn,
Column,
DeleteDateColumn,
OneToMany,
JoinColumn,
OneToOne,
Geometry,
ManyToOne,
} from 'typeorm'
import { Contribution } from '../Contribution'
import { ContributionMessage } from '../ContributionMessage'
import { UserContact } from '../UserContact'
import { UserRole } from '../UserRole'
import { GeometryTransformer } from '../../src/typeorm/GeometryTransformer'
import { Community } from '../Community'
@Entity('users', { engine: 'InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci' })
export class User extends BaseEntity {
@PrimaryGeneratedColumn('increment', { unsigned: true })
id: number
@Column({ type: 'bool', default: false })
foreign: boolean
@Column({
name: 'gradido_id',
length: 36,
nullable: false,
collation: 'utf8mb4_unicode_ci',
})
gradidoID: string
@Column({
name: 'community_uuid',
type: 'char',
length: 36,
nullable: true,
collation: 'utf8mb4_unicode_ci',
})
communityUuid: string
@ManyToOne(() => Community, (community) => community.users)
@JoinColumn({ name: 'community_uuid', referencedColumnName: 'communityUuid' })
community: Community | null
@Column({
name: 'alias',
length: 20,
nullable: true,
default: null,
collation: 'utf8mb4_unicode_ci',
})
alias: string
@OneToOne(() => UserContact, (emailContact: UserContact) => emailContact.user)
@JoinColumn({ name: 'email_id' })
emailContact: UserContact
@Column({ name: 'email_id', type: 'int', unsigned: true, nullable: true, default: null })
emailId: number | null
@Column({
name: 'first_name',
length: 255,
nullable: true,
default: null,
collation: 'utf8mb4_unicode_ci',
})
firstName: string
@Column({
name: 'last_name',
length: 255,
nullable: true,
default: null,
collation: 'utf8mb4_unicode_ci',
})
lastName: string
@Column({ name: 'gms_publish_name', type: 'int', unsigned: true, nullable: false, default: 0 })
gmsPublishName: number
@Column({ name: 'humhub_publish_name', type: 'int', unsigned: true, nullable: false, default: 0 })
humhubPublishName: number
@Column({ name: 'created_at', default: () => 'CURRENT_TIMESTAMP(3)', nullable: false })
createdAt: Date
@DeleteDateColumn({ name: 'deleted_at', nullable: true })
deletedAt: Date | null
@Column({ type: 'bigint', default: 0, unsigned: true })
password: BigInt
@Column({
name: 'password_encryption_type',
type: 'int',
unsigned: true,
nullable: false,
default: 0,
})
passwordEncryptionType: number
@Column({ length: 4, default: 'de', collation: 'utf8mb4_unicode_ci', nullable: false })
language: string
@Column({ type: 'bool', default: false })
hideAmountGDD: boolean
@Column({ type: 'bool', default: false })
hideAmountGDT: boolean
@OneToMany(() => UserRole, (userRole) => userRole.user)
@JoinColumn({ name: 'user_id' })
userRoles: UserRole[]
@Column({ name: 'referrer_id', type: 'int', unsigned: true, nullable: true, default: null })
referrerId?: number | null
@Column({
name: 'contribution_link_id',
type: 'int',
unsigned: true,
nullable: true,
default: null,
})
contributionLinkId?: number | null
@Column({ name: 'publisher_id', default: 0 })
publisherId: number
@Column({ name: 'gms_allowed', type: 'bool', default: true })
gmsAllowed: boolean
@Column({
name: 'location',
type: 'geometry',
default: null,
nullable: true,
transformer: GeometryTransformer,
})
location: Geometry | null
@Column({
name: 'gms_publish_location',
type: 'int',
unsigned: true,
nullable: false,
default: 2,
})
gmsPublishLocation: number
@Column({ name: 'gms_registered', type: 'bool', default: false })
gmsRegistered: boolean
@Column({ name: 'gms_registered_at', type: 'datetime', default: null, nullable: true })
gmsRegisteredAt: Date | null
@Column({ name: 'humhub_allowed', type: 'bool', default: false })
humhubAllowed: boolean
@OneToMany(() => Contribution, (contribution) => contribution.user)
@JoinColumn({ name: 'user_id' })
contributions?: Contribution[]
@OneToMany(() => ContributionMessage, (message) => message.user)
@JoinColumn({ name: 'user_id' })
messages?: ContributionMessage[]
@OneToMany(() => UserContact, (userContact: UserContact) => userContact.user)
@JoinColumn({ name: 'user_id' })
userContacts?: UserContact[]
}

View File

@ -1 +1 @@
export { User } from './0082-introduce_gms_registration/User'
export { User } from './0084-introduce_humhub_registration/User'

View File

@ -0,0 +1,16 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
/* eslint-disable @typescript-eslint/no-explicit-any */
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
await queryFn(
'ALTER TABLE `users` ADD COLUMN IF NOT EXISTS `humhub_allowed` tinyint(1) NOT NULL DEFAULT 0 AFTER `gms_registered_at`;',
)
await queryFn(
'ALTER TABLE `users` ADD COLUMN IF NOT EXISTS `humhub_publish_name` int unsigned NOT NULL DEFAULT 0 AFTER `gms_publish_name`;',
)
}
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
await queryFn('ALTER TABLE `users` DROP COLUMN IF EXISTS `humhub_allowed`;')
await queryFn('ALTER TABLE `users` DROP COLUMN IF EXISTS `humhub_publish_name`;')
}

View File

@ -126,4 +126,7 @@ GMS_ACTIVE=false
GMS_API_URL=http://localhost:4044/
GMS_DASHBOARD_URL=http://localhost:8080/
GMS_WEBHOOK_SECRET=secret
GMS_CREATE_USER_THROW_ERRORS=false
GMS_CREATE_USER_THROW_ERRORS=false
# HUMHUB
HUMHUB_ACTIVE=false

View File

@ -4,7 +4,7 @@ import dotenv from 'dotenv'
dotenv.config()
const constants = {
DB_VERSION: '0083-join_community_federated_communities',
DB_VERSION: '0084-introduce_humhub_registration',
LOG4JS_CONFIG: 'log4js-config.json',
// default log level on production should be info
LOG_LEVEL: process.env.LOG_LEVEL ?? 'info',

View File

@ -10,7 +10,7 @@ Decimal.set({
})
const constants = {
DB_VERSION: '0083-join_community_federated_communities',
DB_VERSION: '0084-introduce_humhub_registration',
DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0
LOG4JS_CONFIG: 'log4js-config.json',
// default log level on production should be info

View File

@ -23,3 +23,4 @@ META_KEYWORDS_EN="Basic Income, Currency, Gratitude, Gift Economy, Natural Econo
META_AUTHOR="Bernd Hückstädt - Gradido-Akademie"
GMS_ACTIVE=false
HUMHUB_ACTIVE=false

View File

@ -25,4 +25,5 @@ META_KEYWORDS_DE=$META_KEYWORDS_DE
META_KEYWORDS_EN=$META_KEYWORDS_EN
META_AUTHOR=$META_AUTHOR
GMS_ACTIVE=$GMS_ACTIVE
GMS_ACTIVE=$GMS_ACTIVE
HUMHUB_ACTIVE=$HUMHUB_ACTIVE

View File

@ -8,7 +8,7 @@ const storeCommitMock = jest.fn()
const localVue = global.localVue
describe('UserGMSNamingFormat', () => {
describe('UserNamingFormat', () => {
let wrapper
beforeEach(() => {
wrapper = mount(UserGMSNamingFormat, {
@ -27,6 +27,9 @@ describe('UserGMSNamingFormat', () => {
localVue,
propsData: {
selectedOption: 'GMS_PUBLISH_NAME_ALIAS_OR_INITALS',
initialValue: 'GMS_PUBLISH_NAME_ALIAS_OR_INITALS',
attrName: 'gmsPublishName',
successMessage: 'success message',
},
})
})
@ -53,16 +56,16 @@ describe('UserGMSNamingFormat', () => {
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'])
expect(wrapper.emitted().valueChanged).toBeTruthy()
expect(wrapper.emitted().valueChanged.length).toBe(1)
expect(wrapper.emitted().valueChanged[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()
expect(wrapper.emitted().valueChanged).toBeFalsy()
})
describe('update with error', () => {

View File

@ -1,5 +1,5 @@
<template>
<div class="user-gms-naming-format">
<div class="user-g-m-s-naming-format">
<b-dropdown v-model="selectedOption">
<template slot="button-content">{{ selectedOptionLabel }}</template>
<b-dropdown-item
@ -19,9 +19,14 @@ import { updateUserInfos } from '@/graphql/mutations'
export default {
name: 'UserGMSNamingFormat',
props: {
initialValue: { type: String, default: 'GMS_PUBLISH_NAME_ALIAS_OR_INITALS' },
attrName: { type: String },
successMessage: { type: String },
},
data() {
return {
selectedOption: this.$store.state.gmsPublishName ?? 'GMS_PUBLISH_NAME_ALIAS_OR_INITALS',
selectedOption: this.initialValue,
dropdownOptions: [
{
label: this.$t('settings.GMS.publish-name.alias-or-initials'),
@ -62,16 +67,16 @@ export default {
return
}
try {
const variables = []
variables[this.attrName] = option.value
await this.$apollo.mutate({
mutation: updateUserInfos,
variables: {
gmsPublishName: option.value,
},
variables,
})
this.toastSuccess(this.$t('settings.GMS.publish-name.updated'))
this.toastSuccess(this.successMessage)
this.selectedOption = option.value
this.$store.commit('gmsPublishName', option.value)
this.$emit('gmsPublishName', option.value)
this.$store.commit(this.attrName, option.value)
this.$emit('valueChanged', option.value)
} catch (error) {
this.toastError(error.message)
}
@ -80,8 +85,8 @@ export default {
}
</script>
<style>
.user-gms-naming-format > .dropdown,
.user-gms-naming-format > .dropdown > .dropdown-toggle > ul.dropdown-menu {
.user-g-m-s-naming-format > .dropdown,
.user-g-m-s-naming-format > .dropdown > .dropdown-toggle > ul.dropdown-menu {
width: 100%;
}
</style>

View File

@ -1,45 +0,0 @@
<template>
<div class="form-user-gms-switch">
<b-form-checkbox
test="BFormCheckbox"
v-model="gmsAllowed"
name="check-button"
switch
@change="onChange"
></b-form-checkbox>
</div>
</template>
<script>
import { updateUserInfos } from '@/graphql/mutations'
export default {
name: 'UserGMSSwitch',
data() {
return {
gmsAllowed: this.$store.state.gmsAllowed,
}
},
methods: {
async onChange() {
this.$apollo
.mutate({
mutation: updateUserInfos,
variables: {
gmsAllowed: this.gmsAllowed,
},
})
.then(() => {
this.$store.commit('gmsAllowed', this.gmsAllowed)
this.$emit('gmsAllowed', this.gmsAllowed)
this.toastSuccess(
this.gmsAllowed ? this.$t('settings.GMS.enabled') : this.$t('settings.GMS.disabled'),
)
})
.catch((error) => {
this.gmsAllowed = this.$store.state.gmsAllowed
this.toastError(error.message)
})
},
},
}
</script>

View File

@ -0,0 +1,86 @@
import { mount } from '@vue/test-utils'
import UserNamingFormat from './UserNamingFormat.vue'
import { toastErrorSpy } from '@test/testSetup'
const mockAPIcall = jest.fn()
const storeCommitMock = jest.fn()
const localVue = global.localVue
describe('UserNamingFormat', () => {
let wrapper
beforeEach(() => {
wrapper = mount(UserNamingFormat, {
mocks: {
$t: (key) => key, // Mocking the translation function
$store: {
state: {
gmsPublishName: null,
},
commit: storeCommitMock,
},
$apollo: {
mutate: mockAPIcall,
},
},
localVue,
propsData: {
selectedOption: 'PUBLISH_NAME_NONE',
initialValue: 'PUBLISH_NAME_NONE',
attrName: 'publishName',
successMessage: 'success message',
},
})
})
afterEach(() => {
wrapper.destroy()
})
it('renders the correct dropdown options', () => {
const dropdownItems = wrapper.findAll('.dropdown-item')
expect(dropdownItems.length).toBe(7)
const labels = dropdownItems.wrappers.map((item) => item.text())
expect(labels).toEqual([
'settings.publish-name.none',
'settings.publish-name.initials',
'settings.publish-name.first',
'settings.publish-name.first-initial',
'settings.publish-name.last',
'settings.publish-name.last-initial',
'settings.publish-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().valueChanged).toBeTruthy()
expect(wrapper.emitted().valueChanged.length).toBe(1)
expect(wrapper.emitted().valueChanged[0]).toEqual(['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().valueChanged).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')
})
})
})

View File

@ -0,0 +1,102 @@
<template>
<div class="user-naming-format">
<b-dropdown v-model="selectedOption">
<template slot="button-content">{{ selectedOptionLabel }}</template>
<b-dropdown-item
v-for="option in dropdownOptions"
@click.prevent="update(option)"
:key="option.value"
:value="option.value"
:title="option.title"
>
{{ option.label }}
</b-dropdown-item>
</b-dropdown>
</div>
</template>
<script>
import { updateUserInfos } from '@/graphql/mutations'
export default {
name: 'UserNamingFormat',
props: {
initialValue: { type: String, default: 'PUBLISH_NAME_NONE' },
attrName: { type: String },
successMessage: { type: String },
},
data() {
return {
selectedOption: this.initialValue,
dropdownOptions: [
{
label: this.$t('settings.publish-name.none'),
title: this.$t('settings.publish-name.none-tooltip'),
value: 'PUBLISH_NAME_NONE',
},
{
label: this.$t('settings.publish-name.initials'),
title: this.$t('settings.publish-name.initials-tooltip'),
value: 'PUBLISH_NAME_INITIALS',
},
{
label: this.$t('settings.publish-name.first'),
title: this.$t('settings.publish-name.first-tooltip'),
value: 'PUBLISH_NAME_FIRST',
},
{
label: this.$t('settings.publish-name.first-initial'),
title: this.$t('settings.publish-name.first-initial-tooltip'),
value: 'PUBLISH_NAME_FIRST_INITIAL',
},
{
label: this.$t('settings.publish-name.last'),
title: this.$t('settings.publish-name.last-tooltip'),
value: 'PUBLISH_NAME_LAST',
},
{
label: this.$t('settings.publish-name.last-initial'),
title: this.$t('settings.publish-name.last-initial-tooltip'),
value: 'PUBLISH_NAME_INITIAL_LAST',
},
{
label: this.$t('settings.publish-name.full'),
title: this.$t('settings.publish-name.full-tooltip'),
value: 'PUBLISH_NAME_FULL',
},
],
}
},
computed: {
selectedOptionLabel() {
return this.dropdownOptions.find((option) => option.value === this.selectedOption).label
},
},
methods: {
async update(option) {
if (option.value === this.selectedOption) {
return
}
try {
const variables = []
variables[this.attrName] = option.value
await this.$apollo.mutate({
mutation: updateUserInfos,
variables,
})
this.toastSuccess(this.successMessage)
this.selectedOption = option.value
this.$store.commit(this.attrName, option.value)
this.$emit('valueChanged', option.value)
} catch (error) {
this.toastError(error.message)
}
},
},
}
</script>
<style>
.user-naming-format > .dropdown,
.user-naming-format > .dropdown > .dropdown-toggle > ul.dropdown-menu {
width: 100%;
}
</style>

View File

@ -0,0 +1,50 @@
<template>
<div class="form-user-switch">
<b-form-checkbox
test="BFormCheckbox"
v-model="value"
name="check-button"
switch
@change="onChange"
></b-form-checkbox>
</div>
</template>
<script>
import { updateUserInfos } from '@/graphql/mutations'
export default {
name: 'UserSettingsSwitch',
props: {
initialValue: { type: Boolean, default: false },
attrName: { type: String },
enabledText: { type: String },
disabledText: { type: String },
},
data() {
return {
value: this.initialValue,
}
},
methods: {
async onChange() {
const variables = []
variables[this.attrName] = this.value
this.$apollo
.mutate({
mutation: updateUserInfos,
variables,
})
.then(() => {
this.$store.commit(this.attrName, this.value)
this.$emit('valueChanged', this.value)
this.toastSuccess(this.value ? this.enabledText : this.disabledText)
})
.catch((error) => {
this.value = this.initialValue
this.toastError(error.message)
})
},
},
}
</script>

View File

@ -22,6 +22,7 @@ const version = {
const features = {
GMS_ACTIVE: process.env.GMS_ACTIVE ?? false,
HUMHUB_ACTIVE: process.env.HUMHUB_ACTIVE ?? false,
}
const environment = {

View File

@ -35,7 +35,9 @@ export const updateUserInfos = gql`
$hideAmountGDD: Boolean
$hideAmountGDT: Boolean
$gmsAllowed: Boolean
$humhubAllowed: Boolean
$gmsPublishName: GmsPublishNameType
$humhubPublishName: PublishNameType
$gmsLocation: Location
$gmsPublishLocation: GmsPublishLocationType
) {
@ -49,7 +51,9 @@ export const updateUserInfos = gql`
hideAmountGDD: $hideAmountGDD
hideAmountGDT: $hideAmountGDT
gmsAllowed: $gmsAllowed
humhubAllowed: $humhubAllowed
gmsPublishName: $gmsPublishName
humhubPublishName: $humhubPublishName
gmsLocation: $gmsLocation
gmsPublishLocation: $gmsPublishLocation
)
@ -173,7 +177,9 @@ export const login = gql`
newsletterState
}
gmsAllowed
humhubAllowed
gmsPublishName
humhubPublishName
gmsPublishLocation
hasElopage
publisherId

View File

@ -9,6 +9,7 @@
"GDD": "GDD",
"GDT": "GDT",
"GMS": "Gradido Karte",
"Humhub": "Gradido Community",
"PersonalDetails": "Persönliche Angaben",
"advanced-calculation": "Vorausberechnung",
"asterisks": "****",
@ -326,6 +327,15 @@
},
"hideAmountGDD": "Dein GDD Betrag ist versteckt.",
"hideAmountGDT": "Dein GDT Betrag ist versteckt.",
"humhub": {
"disabled": "Daten werden nicht in die Gradido Community exportiert",
"enabled": "Daten werden in die Gradido Community exportiert",
"naming-format": "Namensformat in der Gradido Community",
"publish-name": {
"updated": "Namensformat für die Gradido Community aktualisiert."
},
"switch": "Erlaubnis Daten in die Gradido Community zu exportieren."
},
"info": "Transaktionen können nun per Benutzername oder E-Mail-Adresse getätigt werden.",
"language": {
"changeLanguage": "Sprache ändern",
@ -363,6 +373,22 @@
},
"subtitle": "Wenn du dein Passwort vergessen hast, kannst du es hier zurücksetzen."
},
"publish-name": {
"none": "Keine",
"none-tooltip": "Vorname und Nachname bleiben leer",
"first": "Vorname",
"first-tooltip": "Nur der Vornamen, z.B. Max",
"first-initial": "Vorname und Initiale",
"first-initial-tooltip": "Vornamen plus Anfangsbuchstabe des Nachnamens, z.B. Max M.",
"last": "Nachname",
"last-tooltip": "Nur der Nachname, z.B. Mustermann",
"last-initial": "Initiale und Nachname",
"last-initial-tooltip": "Anfangsbuchstabe des Vornamen plus Nachname, z.B. M. Mustermann",
"initials": "Initialen",
"initials-tooltip": "Nur die Initialen von Vor- und Nachname, z.B. M. M.",
"full": "Ganzer Name",
"full-tooltip": "Vollständiger Name: Vorname plus Nachname, z.B. Max Mustermann"
},
"showAmountGDD": "Dein GDD Betrag ist sichtbar.",
"showAmountGDT": "Dein GDT Betrag ist sichtbar.",
"username": {

View File

@ -9,6 +9,7 @@
"GDD": "GDD",
"GDT": "GDT",
"GMS": "Gradido Map",
"Humhub": "Gradido Community",
"PersonalDetails": "Personal details",
"advanced-calculation": "Advanced calculation",
"asterisks": "****",
@ -326,6 +327,15 @@
},
"hideAmountGDD": "Your GDD amount is hidden.",
"hideAmountGDT": "Your GDT amount is hidden.",
"humhub": {
"disabled": "Data not exported into the Gradido Community",
"enabled": "Data exported into the Gradido Community",
"naming-format": "Format of name in the Gradido Community",
"publish-name": {
"updated": "Format of name for the Gradido Community updated."
},
"switch": "Allow data export into the Gradido Community."
},
"info": "Transactions can now be made by username or email address.",
"language": {
"changeLanguage": "Change language",
@ -363,6 +373,22 @@
},
"subtitle": "If you have forgotten your password, you can reset it here."
},
"publish-name": {
"none": "None",
"none-tooltip": "first name and last name are empty",
"first": "first name",
"first-tooltip": "the first name only",
"first-initial": "first name and initial",
"first-initial-tooltip": "first name plus initial of last name",
"last": "last name",
"last-tooltip": "last name only",
"last-initial": "initial and last name",
"last-initial-tooltip": "First letter of the first name plus last name",
"initials": "initials",
"initials-tooltip": "Initials of first name and last name",
"full": "full name",
"full-tooltip": "full name: firstname plus lastname"
},
"showAmountGDD": "Your GDD amount is visible.",
"showAmountGDT": "Your GDT amount is visible.",
"username": {

View File

@ -79,44 +79,90 @@
</b-col>
</b-row>
</b-tab>
<div v-if="isGMS">
<div v-if="isExternService">
<b-tab :title="$t('ExternServices')">
<div class="h2">{{ $t('ExternServices') }}</div>
<div class="h3">{{ $t('GMS') }}</div>
<b-row class="mb-3">
<b-col cols="12" md="6" lg="6">
{{ $t('settings.GMS.switch') }}
<div class="text-small">
{{ gmsAllowed ? $t('settings.GMS.enabled') : $t('settings.GMS.disabled') }}
</div>
</b-col>
<b-col cols="12" md="6" lg="6" class="text-right">
<user-g-m-s-switch @gmsAllowed="gmsStateSwitch" />
</b-col>
</b-row>
<div v-if="gmsAllowed">
<b-row class="mb-4">
<div v-if="isGMS">
<div class="h3">{{ $t('GMS') }}</div>
<b-row class="mb-3">
<b-col cols="12" md="6" lg="6">
{{ $t('settings.GMS.naming-format') }}
{{ $t('settings.GMS.switch') }}
<div class="text-small">
{{ gmsAllowed ? $t('settings.GMS.enabled') : $t('settings.GMS.disabled') }}
</div>
</b-col>
<b-col cols="12" md="6" lg="6">
<user-g-m-s-naming-format />
<b-col cols="12" md="6" lg="6" class="text-right">
<user-settings-switch
@valueChanged="gmsStateSwitch"
:initialValue="$store.state.gmsAllowed"
:attrName="'gmsAllowed'"
:enabledText="$t('settings.GMS.enabled')"
:disabledText="$t('settings.GMS.disabled')"
/>
</b-col>
</b-row>
<b-row class="mb-4">
<div v-if="gmsAllowed">
<b-row class="mb-4">
<b-col cols="12" md="6" lg="6">
{{ $t('settings.GMS.naming-format') }}
</b-col>
<b-col cols="12" md="6" lg="6">
<user-g-m-s-naming-format
:initialValue="$store.state.gmsPublishName"
:attrName="'gmsPublishName'"
:successMessage="$t('settings.GMS.publish-name.updated')"
/>
</b-col>
</b-row>
<b-row class="mb-4">
<b-col cols="12" md="6" lg="6">
{{ $t('settings.GMS.location-format') }}
</b-col>
<b-col cols="12" md="6" lg="6">
<user-g-m-s-location-format />
</b-col>
</b-row>
<b-row class="mb-5">
<b-col cols="12" md="6" lg="6">
{{ $t('settings.GMS.location.label') }}
</b-col>
<b-col cols="12" md="6" lg="6">
<user-g-m-s-location />
</b-col>
</b-row>
</div>
</div>
<div v-if="isHumhub">
<div class="h3">{{ $t('Humhub') }}</div>
<b-row class="mb-3">
<b-col cols="12" md="6" lg="6">
{{ $t('settings.GMS.location-format') }}
{{ $t('settings.humhub.switch') }}
<div class="text-small">
{{
humhubAllowed ? $t('settings.humhub.enabled') : $t('settings.humhub.disabled')
}}
</div>
</b-col>
<b-col cols="12" md="6" lg="6">
<user-g-m-s-location-format />
<b-col cols="12" md="6" lg="6" class="text-right">
<user-settings-switch
@valueChanged="humhubStateSwitch"
:initialValue="$store.state.humhubAllowed"
:attrName="'humhubAllowed'"
:enabledText="$t('settings.humhub.enabled')"
:disabledText="$t('settings.humhub.disabled')"
/>
</b-col>
</b-row>
<b-row class="mb-5">
<b-row v-if="humhubAllowed" class="mb-4">
<b-col cols="12" md="6" lg="6">
{{ $t('settings.GMS.location.label') }}
{{ $t('settings.humhub.naming-format') }}
</b-col>
<b-col cols="12" md="6" lg="6">
<user-g-m-s-location />
<user-naming-format
:initialValue="$store.state.humhubPublishName"
:attrName="'humhubPublishName'"
:successMessage="$t('settings.humhub.publish-name.updated')"
/>
</b-col>
</b-row>
</div>
@ -133,7 +179,7 @@
</div>
</template>
<script>
import UserGMSSwitch from '@/components/UserSettings/UserGMSSwitch'
import UserNamingFormat from '@/components/UserSettings/UserNamingFormat'
import UserGMSNamingFormat from '@/components/UserSettings/UserGMSNamingFormat'
import UserGMSLocationFormat from '@/components/UserSettings/UserGMSLocationFormat'
import UserGMSLocation from '@/components/UserSettings/UserGMSLocation'
@ -141,13 +187,14 @@ import UserName from '@/components/UserSettings/UserName.vue'
import UserPassword from '@/components/UserSettings/UserPassword'
import UserLanguage from '@/components/LanguageSwitch2.vue'
import UserNewsletter from '@/components/UserSettings/UserNewsletter.vue'
import UserSettingsSwitch from '../components/UserSettings/UserSettingsSwitch.vue'
import { updateUserInfos } from '@/graphql/mutations'
import CONFIG from '../config'
export default {
name: 'Profile',
components: {
UserGMSSwitch,
UserNamingFormat,
UserGMSNamingFormat,
UserGMSLocationFormat,
UserGMSLocation,
@ -155,6 +202,7 @@ export default {
UserPassword,
UserLanguage,
UserNewsletter,
UserSettingsSwitch,
},
props: {
balance: { type: Number, default: 0 },
@ -163,16 +211,27 @@ export default {
data() {
const { state } = this.$store
const { darkMode, firstName, lastName, email, newsletterState, gmsAllowed } = state
return {
const {
darkMode,
username: '',
firstName,
lastName,
email,
newsletterState,
gmsAllowed,
humhubAllowed,
} = state
const username = this.$store.state.username || ''
return {
darkMode,
username,
firstName,
lastName,
email,
newsletterState,
gmsAllowed,
humhubAllowed,
mutation: '',
variables: {},
}
@ -183,9 +242,15 @@ export default {
const { firstName, lastName } = this.$store.state
return firstName === this.firstName && lastName === this.lastName
},
isExternService() {
return this.isGMS || this.isHumhub
},
isGMS() {
return CONFIG.GMS_ACTIVE
},
isHumhub() {
return CONFIG.HUMHUB_ACTIVE && this.username
},
},
// TODO: watch: {
// darkMode(val) {
@ -214,6 +279,9 @@ export default {
gmsStateSwitch(eventData) {
this.gmsAllowed = eventData
},
humhubStateSwitch(eventData) {
this.humhubAllowed = eventData
},
},
}
</script>

View File

@ -38,9 +38,15 @@ export const mutations = {
gmsAllowed: (state, gmsAllowed) => {
state.gmsAllowed = gmsAllowed
},
humhubAllowed: (state, humhubAllowed) => {
state.humhubAllowed = humhubAllowed
},
gmsPublishName: (state, gmsPublishName) => {
state.gmsPublishName = gmsPublishName
},
humhubPublishName: (state, humhubPublishName) => {
state.humhubPublishName = humhubPublishName
},
gmsPublishLocation: (state, gmsPublishLocation) => {
state.gmsPublishLocation = gmsPublishLocation
},
@ -81,7 +87,9 @@ export const actions = {
commit('lastName', data.lastName)
commit('newsletterState', data.klickTipp.newsletterState)
commit('gmsAllowed', data.gmsAllowed)
commit('humhubAllowed', data.humhubAllowed)
commit('gmsPublishName', data.gmsPublishName)
commit('humhubPublishName', data.humhubPublishName)
commit('gmsPublishLocation', data.gmsPublishLocation)
commit('hasElopage', data.hasElopage)
commit('publisherId', data.publisherId)
@ -98,7 +106,9 @@ export const actions = {
commit('lastName', '')
commit('newsletterState', null)
commit('gmsAllowed', null)
commit('humhubAllowed', null)
commit('gmsPublishName', null)
commit('humhubPublishName', null)
commit('gmsPublishLocation', null)
commit('hasElopage', false)
commit('publisherId', null)
@ -133,7 +143,9 @@ try {
roles: [],
newsletterState: null,
gmsAllowed: null,
humhubAllowed: null,
gmsPublishName: null,
humhubPublishName: null,
gmsPublishLocation: null,
hasElopage: false,
publisherId: null,

View File

@ -29,7 +29,9 @@ const {
username,
newsletterState,
gmsAllowed,
humhubAllowed,
gmsPublishName,
humhubPublishName,
gmsPublishLocation,
publisherId,
roles,
@ -133,6 +135,14 @@ describe('Vuex store', () => {
})
})
describe('humhubAllowed', () => {
it('sets the state of humhubAllowed', () => {
const state = { humhubAllowed: null }
humhubAllowed(state, true)
expect(state.humhubAllowed).toEqual(true)
})
})
describe('gmsPublishName', () => {
it('sets gmsPublishName', () => {
const state = { gmsPublishName: null }
@ -141,6 +151,14 @@ describe('Vuex store', () => {
})
})
describe('humhubPublishName', () => {
it('sets humhubPublishName', () => {
const state = { humhubPublishName: null }
humhubPublishName(state, 'GMS_PUBLISH_NAME_INITIALS')
expect(state.humhubPublishName).toEqual('GMS_PUBLISH_NAME_INITIALS')
})
})
describe('gmsPublishLocation', () => {
it('sets gmsPublishLocation', () => {
const state = { gmsPublishLocation: null }
@ -218,7 +236,9 @@ describe('Vuex store', () => {
newsletterState: true,
},
gmsAllowed: true,
humhubAllowed: false,
gmsPublishName: 'GMS_PUBLISH_NAME_FULL',
humhubPublishName: 'GMS_PUBLISH_NAME_FULL',
gmsPublishLocation: 'GMS_LOCATION_TYPE_EXACT',
hasElopage: false,
publisherId: 1234,
@ -227,9 +247,9 @@ describe('Vuex store', () => {
hideAmountGDT: true,
}
it('calls fifteen commits', () => {
it('calls seventeen commits', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenCalledTimes(15)
expect(commit).toHaveBeenCalledTimes(17)
})
it('commits gradidoID', () => {
@ -267,39 +287,49 @@ describe('Vuex store', () => {
expect(commit).toHaveBeenNthCalledWith(7, 'gmsAllowed', true)
})
it('commits humhubAllowed', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(8, 'humhubAllowed', false)
})
it('commits gmsPublishName', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(8, 'gmsPublishName', 'GMS_PUBLISH_NAME_FULL')
expect(commit).toHaveBeenNthCalledWith(9, 'gmsPublishName', 'GMS_PUBLISH_NAME_FULL')
})
it('commits humhubPublishName', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(10, 'humhubPublishName', 'GMS_PUBLISH_NAME_FULL')
})
it('commits gmsPublishLocation', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(9, 'gmsPublishLocation', 'GMS_LOCATION_TYPE_EXACT')
expect(commit).toHaveBeenNthCalledWith(11, 'gmsPublishLocation', 'GMS_LOCATION_TYPE_EXACT')
})
it('commits hasElopage', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(10, 'hasElopage', false)
expect(commit).toHaveBeenNthCalledWith(12, 'hasElopage', false)
})
it('commits publisherId', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(11, 'publisherId', 1234)
expect(commit).toHaveBeenNthCalledWith(13, 'publisherId', 1234)
})
it('commits roles', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(12, 'roles', ['admin'])
expect(commit).toHaveBeenNthCalledWith(14, 'roles', ['admin'])
})
it('commits hideAmountGDD', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(13, 'hideAmountGDD', false)
expect(commit).toHaveBeenNthCalledWith(15, 'hideAmountGDD', false)
})
it('commits hideAmountGDT', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(14, 'hideAmountGDT', true)
expect(commit).toHaveBeenNthCalledWith(16, 'hideAmountGDT', true)
})
})
@ -307,9 +337,9 @@ describe('Vuex store', () => {
const commit = jest.fn()
const state = {}
it('calls seventeen commits', () => {
it('calls nineteen commits', () => {
logout({ commit, state })
expect(commit).toHaveBeenCalledTimes(17)
expect(commit).toHaveBeenCalledTimes(19)
})
it('commits token', () => {
@ -347,44 +377,54 @@ describe('Vuex store', () => {
expect(commit).toHaveBeenNthCalledWith(7, 'gmsAllowed', null)
})
it('commits humhubAllowed', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(8, 'humhubAllowed', null)
})
it('commits gmsPublishName', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(8, 'gmsPublishName', null)
expect(commit).toHaveBeenNthCalledWith(9, 'gmsPublishName', null)
})
it('commits humhubPublishName', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(10, 'humhubPublishName', null)
})
it('commits gmsPublishLocation', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(9, 'gmsPublishLocation', null)
expect(commit).toHaveBeenNthCalledWith(11, 'gmsPublishLocation', null)
})
it('commits hasElopage', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(10, 'hasElopage', false)
expect(commit).toHaveBeenNthCalledWith(12, 'hasElopage', false)
})
it('commits publisherId', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(11, 'publisherId', null)
expect(commit).toHaveBeenNthCalledWith(13, 'publisherId', null)
})
it('commits roles', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(12, 'roles', null)
expect(commit).toHaveBeenNthCalledWith(14, 'roles', null)
})
it('commits hideAmountGDD', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(13, 'hideAmountGDD', false)
expect(commit).toHaveBeenNthCalledWith(15, 'hideAmountGDD', false)
})
it('commits hideAmountGDT', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(14, 'hideAmountGDT', true)
expect(commit).toHaveBeenNthCalledWith(16, 'hideAmountGDT', true)
})
it('commits email', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(15, 'email', '')
expect(commit).toHaveBeenNthCalledWith(17, 'email', '')
})
// how to get this working?