feat(webapp): implement configurable custom button in header (#8215)

* Implement configurable custom button in header

* Implement default values for 'headerMenu'

---------

Co-authored-by: mahula <lenzmath@posteo.de>
This commit is contained in:
Wolfgang Huß 2025-03-01 08:00:41 +01:00 committed by GitHub
parent 628b57aa29
commit 87e5fc6bf8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 125 additions and 17 deletions

View File

@ -0,0 +1,74 @@
<template>
<div>
<a v-if="settings.url" :href="settings.url" :target="settings.target">
<base-button
class="custom-button"
circle
ghost
v-tooltip="{
content: $t(settings.toolTipIdent),
placement: 'bottom-start',
}"
>
<img
class="logo-svg"
:src="settings.iconPath"
:alt="settings.iconAltText"
:style="logoWidthStyle"
/>
</base-button>
</a>
<nuxt-link v-else :to="settings.toolTipIdent">
<base-button
class="custom-button"
circle
ghost
v-tooltip="{
content: $t(settings.toolTipIdent),
placement: 'bottom-start',
}"
>
<img
class="logo-svg"
:src="settings.iconPath"
:alt="settings.iconAltText"
:style="logoWidthStyle"
/>
</base-button>
</nuxt-link>
</div>
</template>
<script>
import isEmpty from 'lodash/isEmpty'
export default {
name: 'CustomButton',
props: {
settings: { type: Object, required: true },
},
data() {
return {
isEmpty,
}
},
computed: {
logoWidthStyle() {
const width = this.isEmpty(this.settings.iconWidth) ? '26px' : this.settings.iconWidth
return `width: ${width};`
},
},
}
</script>
<style lang="scss">
.custom-button {
margin-left: 4px;
margin-right: 4px;
}
.logo-svg {
height: auto;
fill: #000000;
}
</style>

View File

@ -96,6 +96,10 @@
<client-only v-if="!isEmpty(this.$env.MAPBOX_TOKEN)"> <client-only v-if="!isEmpty(this.$env.MAPBOX_TOKEN)">
<map-button /> <map-button />
</client-only> </client-only>
<!-- custom button -->
<client-only v-if="!isEmpty(customButton)">
<custom-button :settings="customButton" />
</client-only>
<!-- avatar menu --> <!-- avatar menu -->
<client-only> <client-only>
<avatar-menu placement="top" /> <avatar-menu placement="top" />
@ -214,6 +218,18 @@
</div> </div>
</client-only> </client-only>
</ds-flex-item> </ds-flex-item>
<!-- custom button -->
<ds-flex-item
v-if="!isEmpty(customButton)"
:class="{ 'hide-mobile-menu': !toggleMobileMenu }"
style="text-align: center"
>
<client-only>
<div @click="toggleMobileMenuView">
<custom-button :settings="customButton" />
</div>
</client-only>
</ds-flex-item>
<!-- avatar menu mobile --> <!-- avatar menu mobile -->
<ds-flex-item :class="{ 'hide-mobile-menu': !toggleMobileMenu }" style="text-align: end"> <ds-flex-item :class="{ 'hide-mobile-menu': !toggleMobileMenu }" style="text-align: end">
<client-only> <client-only>
@ -271,9 +287,10 @@ import { SHOW_CONTENT_FILTER_HEADER_MENU } from '~/constants/filter.js'
import LOGOS from '~/constants/logos.js' import LOGOS from '~/constants/logos.js'
import AvatarMenu from '~/components/AvatarMenu/AvatarMenu' import AvatarMenu from '~/components/AvatarMenu/AvatarMenu'
import ChatNotificationMenu from '~/components/ChatNotificationMenu/ChatNotificationMenu' import ChatNotificationMenu from '~/components/ChatNotificationMenu/ChatNotificationMenu'
import CustomButton from '~/components/CustomButton/CustomButton'
import FilterMenu from '~/components/FilterMenu/FilterMenu.vue' import FilterMenu from '~/components/FilterMenu/FilterMenu.vue'
import GroupButton from '~/components/Group/GroupButton' import GroupButton from '~/components/Group/GroupButton'
import headerMenu from '~/constants/headerMenu.js' import headerMenuBranded from '~/constants/headerMenuBranded.js'
import InviteButton from '~/components/InviteButton/InviteButton' import InviteButton from '~/components/InviteButton/InviteButton'
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch' import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
import Logo from '~/components/Logo/Logo' import Logo from '~/components/Logo/Logo'
@ -286,6 +303,8 @@ import PageParamsLink from '~/components/_new/features/PageParamsLink/PageParams
export default { export default {
components: { components: {
AvatarMenu, AvatarMenu,
ChatNotificationMenu,
CustomButton,
FilterMenu, FilterMenu,
GroupButton, GroupButton,
InviteButton, InviteButton,
@ -295,7 +314,6 @@ export default {
NotificationMenu, NotificationMenu,
PageParamsLink, PageParamsLink,
SearchField, SearchField,
ChatNotificationMenu,
}, },
props: { props: {
showMobileMenu: { type: Boolean, default: false }, showMobileMenu: { type: Boolean, default: false },
@ -309,8 +327,9 @@ export default {
LOGOS, LOGOS,
SHOW_GROUP_BUTTON_IN_HEADER, SHOW_GROUP_BUTTON_IN_HEADER,
SHOW_CONTENT_FILTER_HEADER_MENU, SHOW_CONTENT_FILTER_HEADER_MENU,
isHeaderMenu: headerMenu.MENU.length > 0, isHeaderMenu: headerMenuBranded.MENU.length > 0,
menu: headerMenu.MENU, customButton: headerMenuBranded.CUSTOM_BUTTON,
menu: headerMenuBranded.MENU,
mobileSearchVisible: false, mobileSearchVisible: false,
toggleMobileMenu: false, toggleMobileMenu: false,
inviteRegistration: this.$env.INVITE_REGISTRATION === true, // for 'false' in .env INVITE_REGISTRATION is of type undefined and not(!) boolean false, because of internal handling, inviteRegistration: this.$env.INVITE_REGISTRATION === true, // for 'false' in .env INVITE_REGISTRATION is of type undefined and not(!) boolean false, because of internal handling,

View File

@ -1,13 +1 @@
export default { export default {}
MENU: [
// {
// nameIdent: 'nameIdent',
// path: '/',
// },
// {
// nameIdent: 'nameIdent',
// url: 'https://ocelot.social',
// target: '_blank',
// },
],
}

View File

@ -0,0 +1,27 @@
import { merge } from 'lodash'
import headerMenu from '~/constants/headerMenu.js'
const defaultHeaderMenu = {
CUSTOM_BUTTON: {
// iconPath: '/img/custom/X',
// iconWidth: '28px',
// iconAltText: 'X',
// toolTipIdent: 'nameIdent',
// path: '/',
// url: 'https://ocelot.social/en/donate',
// target: '_blank',
},
MENU: [
// {
// nameIdent: 'nameIdent',
// path: '/',
// },
// {
// nameIdent: 'nameIdent',
// url: 'https://ocelot.social',
// target: '_blank',
// },
],
}
export default merge(defaultHeaderMenu, headerMenu)