Merge pull request #3543 from gradido/frontend_show_gradido_id

feat(frontend): gradido id under avatar instead of email
This commit is contained in:
einhornimmond 2025-10-09 09:57:43 +02:00 committed by GitHub
commit 46c4711edb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 108 additions and 18 deletions

View File

@ -29,7 +29,7 @@
:title="$t('copy-to-clipboard')"
@click="copyToClipboard(message.content)"
>
<IBiClipboard></IBiClipboard>
<IBiCopy></IBiCopy>
</b-button>
</div>
</div>

View File

@ -23,4 +23,10 @@ export default {
margin-bottom: 1rem;
padding: 0.75rem 1rem;
}
@media screen and (width <= 450px) {
.page-breadcrumb {
margin-top: 3rem;
}
}
</style>

View File

@ -5,6 +5,8 @@ import { createStore } from 'vuex'
import Navbar from './Navbar.vue'
import { BImg, BNavbar, BNavbarBrand, BNavbarNav } from 'bootstrap-vue-next'
import AppAvatar from '@/components/AppAvatar.vue'
import { createI18n } from 'vue-i18n'
import CONFIG from '@/config'
// Mock vue-avatar
vi.mock('vue-avatar', () => ({
@ -17,6 +19,16 @@ vi.mock('vue-avatar', () => ({
},
}))
const i18n = createI18n({
legacy: false,
locale: 'en',
messages: {
en: {
'copied-to-clipboard': 'copied-to-clipboard',
},
},
})
const createVuexStore = (state = {}) =>
createStore({
state: () => ({
@ -24,6 +36,7 @@ const createVuexStore = (state = {}) =>
lastName: 'User',
gradidoID: 'current-user-id',
email: 'test@example.com',
username: 'username',
...state,
}),
})
@ -41,7 +54,10 @@ describe('Navbar', () => {
store = createVuexStore(storeState)
return mount(Navbar, {
global: {
plugins: [store, router],
plugins: [store, router, i18n],
stubs: {
IBiClipboard: true,
},
mocks: {
$t: (msg) => msg,
},
@ -89,7 +105,9 @@ describe('Navbar', () => {
})
it('has the email address', () => {
expect(wrapper.find('div[data-test="navbar-item-email"]').text()).toBe('test@example.com')
expect(wrapper.find('div[data-test="navbar-item-gradido-id"]').text()).toBe(
`${CONFIG.COMMUNITY_NAME}/username`,
)
})
})
})

View File

@ -3,12 +3,14 @@
<div class="navbar-element">
<BNavbar toggleable="lg" class="pe-4">
<BNavbarBrand>
<BImg
class="mt-lg--2 mt-3 mb-3 d-none d-lg-block zindex10"
:src="logo"
width="200"
alt="Logo"
/>
<router-link to="/overview">
<BImg
class="mt-lg--2 mt-3 mb-3 d-none d-lg-block zindex10"
:src="logo"
width="200"
alt="Logo"
/>
</router-link>
<div v-b-toggle.sidebar-mobile variant="link" class="d-block d-lg-none">
<span class="navbar-toggler-icon h2"></span>
</div>
@ -17,9 +19,9 @@
<BImg class="sheet-img position-absolute zindex-1" :src="sheet"></BImg>
<BNavbarNav class="ms-auto" right>
<router-link to="/settings">
<div class="d-flex align-items-center">
<div class="me-3">
<div class="">
<router-link to="/settings" class="d-flex flex-column align-items-end text-end">
<div class="ms-auto">
<app-avatar
class="vue3-avatar"
:name="username.username"
@ -29,12 +31,35 @@
:size="61"
/>
</div>
<div>
<div data-test="navbar-item-username">{{ username.username }}</div>
<div data-test="navbar-item-email">{{ $store.state.email }}</div>
<div v-if="!hasUsername">
<div class="mt-3" data-test="navbar-item-username">{{ username.username }}</div>
<div class="small mt-1" data-test="navbar-item-gradido-id">{{ gradidoId }}</div>
</div>
</router-link>
<div class="d-flex flex-column align-items-end text-end">
<div
v-if="hasUsername"
class="navbar-like-link mt-3"
data-test="navbar-item-username"
>
{{ username.username }}
</div>
<div
v-if="hasUsername"
class="small navbar-like-link pointer mt-1"
data-test="navbar-item-gradido-id"
>
<a
class="copy-clipboard-button"
:title="$t('copy-to-clipboard')"
@click="copyToClipboard(gradidoId)"
>
<IBiCopy></IBiCopy>
{{ gradidoId }}
</a>
</div>
</div>
</router-link>
</div>
</BNavbarNav>
</BNavbar>
<!-- <div class="alert-box">
@ -47,11 +72,20 @@
</template>
<script>
import CONFIG from '@/config'
import { useAppToast } from '@/composables/useToast'
export default {
name: 'Navbar',
props: {
balance: { type: Number, required: true },
},
setup() {
const toast = useAppToast()
return {
toast,
}
},
data() {
return {
logo: '/img/brand/gradido-logo.png',
@ -65,6 +99,21 @@ export default {
initials: `${this.$store.state.firstName[0]}${this.$store.state.lastName[0]}`,
}
},
hasUsername() {
return this.$store.state.username && this.$store.state.username.length > 0
},
gradidoId() {
const name = this.$store.state.username
? this.$store.state.username
: this.$store.state.gradidoId
return `${CONFIG.COMMUNITY_NAME}/${name}`
},
},
methods: {
copyToClipboard(content) {
navigator.clipboard.writeText(content)
this.toast.toastSuccess(this.$t('gradidoid-copied-to-clipboard'))
},
},
}
</script>
@ -83,6 +132,10 @@ export default {
font-size: 2.25rem;
}
.navbar-like-link {
color: rgba(var(--bs-link-color-rgb));
}
button.navbar-toggler > span.navbar-toggler-icon {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(4, 112, 6, 1)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}

View File

@ -94,7 +94,8 @@ onResult(({ data }) => {
onError(() => {
isUserSearchDisabled.value = true
if (gmsAllowed.value && gmsUserLocationExists.value) {
toastError('authenticateGmsUserSearch failed!')
// setting isUserSearchDisabled.value to true will show that GMS is offline, no need to further post to the user
// toastError('authenticateGmsUserSearch failed!')
} else if (gmsAllowed.value && !gmsUserLocationExists.value) {
// toastError('capture your location first!')
// eslint-disable-next-line no-console

View File

@ -114,6 +114,7 @@
"thanksYouWith": "dankt dir mit"
},
"contributionText": "Beitragstext",
"copy-to-clipboard": "In Zwischenablage kopieren",
"creation": "Schöpfen",
"decay": {
"before_startblock_transaction": "Diese Transaktion beinhaltet keine Vergänglichkeit.",
@ -306,6 +307,7 @@
"raise": "Erhöhung",
"recruited-member": "Eingeladenes Mitglied"
},
"gradidoid-copied-to-clipboard": "Gradido ID wurde in die Zwischenablage kopiert.",
"h": "h",
"info": "Information",
"language": "Sprache",

View File

@ -114,6 +114,7 @@
"thanksYouWith": "thanks you with"
},
"contributionText": "Contribution Text",
"copy-to-clipboard": "Copy to clipboard",
"creation": "Creation",
"decay": {
"before_startblock_transaction": "This transaction does not include decay.",
@ -306,6 +307,7 @@
"raise": "Increase",
"recruited-member": "Invited member"
},
"gradidoid-copied-to-clipboard": "Gradido ID copied to clipboard.",
"h": "h",
"info": "Information",
"language": "Language",

View File

@ -101,6 +101,7 @@
"thanksYouWith": "te agradece con",
"unique": "(único)"
},
"copy-to-clipboard": "Copiar al portapapeles",
"decay": {
"before_startblock_transaction": "Esta transacción no implica disminución en su valor.",
"calculation_decay": "Cálculo de la disminución gradual del valor",
@ -255,6 +256,7 @@
"raise": "Aumento",
"recruited-member": "Miembro invitado"
},
"gradidoid-copied-to-clipboard": "Gradido ID copiado al portapapeles.",
"info": "Información",
"language": "Idioma",
"link-load": "recargar el último enlace | recargar los últimos {n} enlaces",

View File

@ -103,6 +103,7 @@
"unique": "(unique)"
},
"contributionText": "Texte de la contribution",
"copy-to-clipboard": "Copier dans le presse-papier",
"creation": "Création",
"decay": {
"before_startblock_transaction": "Cette transaction n'est pas péremptoire.",
@ -262,6 +263,7 @@
"raise": "Augmentation",
"recruited-member": "Membre invité"
},
"gradidoid-copied-to-clipboard": "Gradido ID copié dans le presse-papier.",
"h": "h",
"info": "Information",
"language": "Langage",

View File

@ -101,6 +101,7 @@
"thanksYouWith": "bedankt jou met",
"unique": "(uniek)"
},
"copy-to-clipboard": "Kopieer naar klembord",
"decay": {
"before_startblock_transaction": "Deze transactie heeft geen vergankelijkheid.",
"calculation_decay": "Berekening van de vergankelijkheid",
@ -255,6 +256,7 @@
"raise": "Verhoging",
"recruited-member": "Uitgenodigd lid"
},
"gradidoid-copied-to-clipboard": "Gradido ID gekopieerd naar klembord.",
"info": "Informatie",
"language": "Taal",
"link-load": "de laatste link herladen | de laatste links herladen",

View File

@ -125,7 +125,7 @@ export default defineConfig(async ({ command }) => {
GRAPHQL_URI: CONFIG.GRAPHQL_URI, // null,
ADMIN_AUTH_PATH: CONFIG.ADMIN_AUTH_PATH ?? null, // it is the only env without exported default
ADMIN_AUTH_URL: CONFIG.ADMIN_AUTH_URL, // null,
COMMUNITY_NAME: null,
COMMUNITY_NAME: CONFIG.COMMUNITY_NAME,
COMMUNITY_REGISTER_PATH: null,
COMMUNITY_REGISTER_URL: null,
COMMUNITY_DESCRIPTION: null,

View File

@ -22,6 +22,8 @@ const RESERVED_ALIAS = [
'user',
'usr',
'var',
'reserved',
'undefined'
]
export const aliasSchema = string()