Merge pull request #5590 from Ocelot-Social-Community/5545-Footer-And-Header-Links-Configurable

feat: 🍰 Footer And Header Links Configurable To Have External Link Target
This commit is contained in:
Wolfgang Huß 2022-10-28 13:46:02 +02:00 committed by GitHub
commit 7f26c0184a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 128 additions and 50 deletions

View File

@ -87,12 +87,7 @@
</ds-chip> </ds-chip>
</template> </template>
<template #edit="scope"> <template #edit="scope">
<ds-button <ds-button v-if="scope.row.myRoleInGroup !== 'owner'" size="small" primary disabled>
v-if="scope.row.myRoleInGroup !== 'owner'"
size="small"
primary
@click="deleteMember(scope.row.id)"
>
<!-- TODO: implement removal of group members --> <!-- TODO: implement removal of group members -->
<!-- :disabled="scope.row.myRoleInGroup === 'owner'" <!-- :disabled="scope.row.myRoleInGroup === 'owner'"
--> -->
@ -221,14 +216,6 @@ export default {
} finally { } finally {
} }
}, },
// TODO: implement removal of group members
// openModal(row) {
// this.isOpen = true
// this.memberId = row.id
// },
deleteMember(id) {
alert('deleteMember: ' + id)
},
}, },
} }
</script> </script>

View File

@ -28,7 +28,7 @@
:width="{ base: 'auto' }" :width="{ base: 'auto' }"
style="margin-right: 20px" style="margin-right: 20px"
> >
<a v-if="item.url" :href="item.url" target="_blank"> <a v-if="item.url" :href="item.url" :target="item.target">
<ds-text size="large" bold> <ds-text size="large" bold>
{{ $t(item.nameIdent) }} {{ $t(item.nameIdent) }}
</ds-text> </ds-text>
@ -78,8 +78,12 @@
<invite-button placement="top" /> <invite-button placement="top" />
</client-only> </client-only>
</div> </div>
<!-- group button -->
<client-only v-if="SHOW_GROUP_BUTTON_IN_HEADER">
<group-button />
</client-only>
<!-- avatar-menu -->
<client-only> <client-only>
<!-- avatar-menu -->
<avatar-menu placement="top" /> <avatar-menu placement="top" />
</client-only> </client-only>
</template> </template>
@ -154,9 +158,18 @@
<invite-button placement="top" /> <invite-button placement="top" />
</client-only> </client-only>
</ds-flex-item> </ds-flex-item>
<!-- group button -->
<ds-flex-item
:class="{ 'hide-mobile-menu': !toggleMobileMenu }"
style="text-align: center"
>
<client-only v-if="SHOW_GROUP_BUTTON_IN_HEADER">
<group-button />
</client-only>
</ds-flex-item>
<!-- 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>
<!-- avatar-menu mobile-->
<avatar-menu placement="top" /> <avatar-menu placement="top" />
</client-only> </client-only>
</ds-flex-item> </ds-flex-item>
@ -165,7 +178,7 @@
<!-- dynamic branding menu --> <!-- dynamic branding menu -->
<ul v-if="isHeaderMenu" class="dynamic-branding-mobil"> <ul v-if="isHeaderMenu" class="dynamic-branding-mobil">
<li v-for="item in menu" :key="item.name"> <li v-for="item in menu" :key="item.name">
<a v-if="item.url" :href="item.url" target="_blank"> <a v-if="item.url" :href="item.url" :target="item.target">
<ds-text size="large" bold> <ds-text size="large" bold>
{{ $t(item.nameIdent) }} {{ $t(item.nameIdent) }}
</ds-text> </ds-text>
@ -193,10 +206,12 @@
</template> </template>
<script> <script>
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import { SHOW_GROUP_BUTTON_IN_HEADER } from '~/constants/groups.js'
import LOGOS from '~/constants/logos.js' import LOGOS from '~/constants/logos.js'
import headerMenu from '~/constants/headerMenu.js' import headerMenu from '~/constants/headerMenu.js'
import AvatarMenu from '~/components/AvatarMenu/AvatarMenu' import AvatarMenu from '~/components/AvatarMenu/AvatarMenu'
import FilterMenu from '~/components/FilterMenu/FilterMenu.vue' import FilterMenu from '~/components/FilterMenu/FilterMenu.vue'
import GroupButton from '~/components/Group/GroupButton'
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'
@ -209,6 +224,7 @@ export default {
components: { components: {
AvatarMenu, AvatarMenu,
FilterMenu, FilterMenu,
GroupButton,
InviteButton, InviteButton,
LocaleSwitch, LocaleSwitch,
Logo, Logo,
@ -223,6 +239,7 @@ export default {
return { return {
links, links,
LOGOS, LOGOS,
SHOW_GROUP_BUTTON_IN_HEADER,
isHeaderMenu: headerMenu.MENU.length > 0, isHeaderMenu: headerMenu.MENU.length > 0,
menu: headerMenu.MENU, menu: headerMenu.MENU,
mobileSearchVisible: false, mobileSearchVisible: false,

View File

@ -100,21 +100,41 @@ describe('PageFooter.vue', () => {
const links = { const links = {
...linksDefault, ...linksDefault,
ORGANIZATION: linksDefault.ORGANIZATION.overwrite({ ORGANIZATION: linksDefault.ORGANIZATION.overwrite({
externalLink: 'https://ocelot.social', externalLink: {
url: 'https://ocelot.social',
target: '_blank',
},
}), }),
IMPRINT: linksDefault.IMPRINT.overwrite({ IMPRINT: linksDefault.IMPRINT.overwrite({
externalLink: 'https://ocelot.social/IMPRINT', externalLink: {
url: 'https://ocelot.social/IMPRINT',
target: '_blank',
},
}), }),
TERMS_AND_CONDITIONS: linksDefault.TERMS_AND_CONDITIONS.overwrite({ TERMS_AND_CONDITIONS: linksDefault.TERMS_AND_CONDITIONS.overwrite({
externalLink: 'https://ocelot.social/TERMS_AND_CONDITIONS', externalLink: {
url: 'https://ocelot.social/TERMS_AND_CONDITIONS',
target: '_blank',
},
}), }),
CODE_OF_CONDUCT: linksDefault.CODE_OF_CONDUCT.overwrite({ CODE_OF_CONDUCT: linksDefault.CODE_OF_CONDUCT.overwrite({
externalLink: 'https://ocelot.social/CODE_OF_CONDUCT', externalLink: {
url: 'https://ocelot.social/CODE_OF_CONDUCT',
target: '_blank',
},
}), }),
DATA_PRIVACY: linksDefault.DATA_PRIVACY.overwrite({ DATA_PRIVACY: linksDefault.DATA_PRIVACY.overwrite({
externalLink: 'https://ocelot.social/DATA_PRIVACY', externalLink: {
url: 'https://ocelot.social/DATA_PRIVACY',
target: '_blank',
},
}),
FAQ: linksDefault.FAQ.overwrite({
externalLink: {
url: 'https://ocelot.social/FAQ',
target: '_blank',
},
}), }),
FAQ: linksDefault.FAQ.overwrite({ externalLink: 'https://ocelot.social/FAQ' }),
} }
wrapper = Wrapper() wrapper = Wrapper()
wrapper.setData({ links }) wrapper.setData({ links })

View File

@ -6,7 +6,12 @@
> >
<slot /> <slot />
</nuxt-link> </nuxt-link>
<a v-else :href="pageParams.externalLink" target="_blank" :data-test="pageParams.name + '-link'"> <a
v-else
:href="pageParams.externalLink.url"
:target="pageParams.externalLink.target"
:data-test="pageParams.name + '-link'"
>
<slot /> <slot />
</a> </a>
</template> </template>

View File

@ -4,7 +4,11 @@ export const defaultPageParamsPages = {
ORGANIZATION: new PageParams({ ORGANIZATION: new PageParams({
name: 'organization', name: 'organization',
externalLink: null, // if string is defined and not empty it's dominating // externalLink: {
// url: 'https://ocelot.social',
// target: '_blank',
// },
externalLink: null, // if defined it's dominating
internalPage: { internalPage: {
pageRoute: '/organization', // static, don't change! internal page in case no external is defined pageRoute: '/organization', // static, don't change! internal page in case no external is defined
@ -21,7 +25,11 @@ export const defaultPageParamsPages = {
DONATE: new PageParams({ DONATE: new PageParams({
name: 'donate', name: 'donate',
externalLink: null, // if string is defined and not empty it's dominating // externalLink: {
// url: 'https://ocelot.social',
// target: '_blank',
// },
externalLink: null, // if defined it's dominating
internalPage: { internalPage: {
pageRoute: '/donate', // static, don't change! internal page in case no external is defined pageRoute: '/donate', // static, don't change! internal page in case no external is defined
@ -38,7 +46,11 @@ export const defaultPageParamsPages = {
IMPRINT: new PageParams({ IMPRINT: new PageParams({
name: 'imprint', name: 'imprint',
externalLink: null, // if string is defined and not empty it's dominating // externalLink: {
// url: 'https://ocelot.social',
// target: '_blank',
// },
externalLink: null, // if defined it's dominating
internalPage: { internalPage: {
pageRoute: '/imprint', // static, don't change! internal page in case no external is defined pageRoute: '/imprint', // static, don't change! internal page in case no external is defined
@ -55,7 +67,11 @@ export const defaultPageParamsPages = {
TERMS_AND_CONDITIONS: new PageParams({ TERMS_AND_CONDITIONS: new PageParams({
name: 'terms-and-conditions', name: 'terms-and-conditions',
externalLink: null, // if string is defined and not empty it's dominating // externalLink: {
// url: 'https://ocelot.social',
// target: '_blank',
// },
externalLink: null, // if defined it's dominating
internalPage: { internalPage: {
pageRoute: '/terms-and-conditions', // static, don't change! internal page in case no external is defined pageRoute: '/terms-and-conditions', // static, don't change! internal page in case no external is defined
@ -72,7 +88,11 @@ export const defaultPageParamsPages = {
CODE_OF_CONDUCT: new PageParams({ CODE_OF_CONDUCT: new PageParams({
name: 'code-of-conduct', name: 'code-of-conduct',
externalLink: null, // if string is defined and not empty it's dominating // externalLink: {
// url: 'https://ocelot.social',
// target: '_blank',
// },
externalLink: null, // if defined it's dominating
internalPage: { internalPage: {
pageRoute: '/code-of-conduct', // static, don't change! internal page in case no external is defined pageRoute: '/code-of-conduct', // static, don't change! internal page in case no external is defined
@ -89,7 +109,11 @@ export const defaultPageParamsPages = {
DATA_PRIVACY: new PageParams({ DATA_PRIVACY: new PageParams({
name: 'data-privacy', name: 'data-privacy',
externalLink: null, // if string is defined and not empty it's dominating // externalLink: {
// url: 'https://ocelot.social',
// target: '_blank',
// },
externalLink: null, // if defined it's dominating
internalPage: { internalPage: {
pageRoute: '/data-privacy', // static, don't change! internal page in case no external is defined pageRoute: '/data-privacy', // static, don't change! internal page in case no external is defined
@ -106,7 +130,11 @@ export const defaultPageParamsPages = {
FAQ: new PageParams({ FAQ: new PageParams({
name: 'faq', name: 'faq',
externalLink: null, // if string is defined and not empty it's dominating // externalLink: {
// url: 'https://ocelot.social',
// target: '_blank',
// },
externalLink: null, // if defined it's dominating
internalPage: { internalPage: {
pageRoute: '/faq', // static, don't change! internal page in case no external is defined pageRoute: '/faq', // static, don't change! internal page in case no external is defined
@ -123,7 +151,11 @@ export const defaultPageParamsPages = {
SUPPORT: new PageParams({ SUPPORT: new PageParams({
name: 'support', name: 'support',
externalLink: null, // externalLink: {
// url: 'https://ocelot.social',
// target: '_blank',
// },
externalLink: null, // if defined it's dominating
internalPage: { internalPage: {
pageRoute: '/support', // static, don't change '*/support'! internal page in case no external is defined pageRoute: '/support', // static, don't change '*/support'! internal page in case no external is defined

View File

@ -24,18 +24,22 @@ export class PageParams {
} }
get isInternalPage() { get isInternalPage() {
return this.noStringDefined(this.externalLink) return !(this.externalLink && !this.noStringDefined(this.externalLink.url))
} }
get link() { get link() {
return this.isInternalPage ? this.internalPage.pageRoute : this.externalLink return this.isInternalPage ? this.internalPage.pageRoute : this.externalLink.url
} }
redirectToPage(thisComponent) { redirectToPage(thisComponent) {
if (this.isInternalPage) { if (this.isInternalPage) {
thisComponent.$router.push(this.internalPage.pageRoute) thisComponent.$router.push(this.internalPage.pageRoute)
} else if (typeof window !== 'undefined') { } else if (typeof window !== 'undefined') {
window.location.href = this.externalLink if (this.externalLink.target === '_blank') {
window.open(this.externalLink.url, this.externalLink.target)
} else {
window.location.href = this.externalLink.url
}
} }
} }
} }

View File

@ -7,6 +7,7 @@ export default {
// { // {
// nameIdent: 'nameIdent', // nameIdent: 'nameIdent',
// url: 'https://ocelot.social', // url: 'https://ocelot.social',
// target: '_blank',
// }, // },
], ],
} }

View File

@ -3,7 +3,11 @@
import { defaultPageParamsPages } from '~/components/utils/InternalPages.js' import { defaultPageParamsPages } from '~/components/utils/InternalPages.js'
const ORGANIZATION = defaultPageParamsPages.ORGANIZATION.overwrite({ const ORGANIZATION = defaultPageParamsPages.ORGANIZATION.overwrite({
externalLink: 'https://ocelot.social', // if string is defined and not empty it's dominating // if defined it's dominating
externalLink: {
url: 'https://ocelot.social',
target: '_blank',
},
internalPage: { internalPage: {
// footerIdent: 'site.made', // localized string identifier, if undefined default is used // footerIdent: 'site.made', // localized string identifier, if undefined default is used
@ -16,8 +20,12 @@ const ORGANIZATION = defaultPageParamsPages.ORGANIZATION.overwrite({
}, },
}) })
const DONATE = defaultPageParamsPages.DONATE.overwrite({ const DONATE = defaultPageParamsPages.DONATE.overwrite({
// we use 'ocelot-social.herokuapp.com' at the moment, because redirections of 'ocelot.social' subpages are not working correctly // if defined it's dominating
externalLink: 'https://ocelot-social.herokuapp.com/donations', // if string is defined and not empty it's dominating externalLink: {
// we use 'ocelot-social.herokuapp.com' at the moment, because redirections of 'ocelot.social' subpages are not working correctly
url: 'https://ocelot-social.herokuapp.com/donations',
target: '_blank',
},
internalPage: { internalPage: {
// footerIdent: 'site.donate', // localized string identifier, if undefined default is used // footerIdent: 'site.donate', // localized string identifier, if undefined default is used
@ -30,8 +38,11 @@ const DONATE = defaultPageParamsPages.DONATE.overwrite({
}, },
}) })
const IMPRINT = defaultPageParamsPages.IMPRINT.overwrite({ const IMPRINT = defaultPageParamsPages.IMPRINT.overwrite({
// we use 'ocelot-social.herokuapp.com' at the moment, because redirections of 'ocelot.social' subpages are not working correctly externalLink: {
externalLink: 'https://ocelot-social.herokuapp.com/imprint', // if string is defined and not empty it's dominating // we use 'ocelot-social.herokuapp.com' at the moment, because redirections of 'ocelot.social' subpages are not working correctly
url: 'https://ocelot-social.herokuapp.com/imprint',
target: '_blank',
},
internalPage: { internalPage: {
// footerIdent: 'site.imprint', // localized string identifier, if undefined default is used // footerIdent: 'site.imprint', // localized string identifier, if undefined default is used
@ -44,7 +55,7 @@ const IMPRINT = defaultPageParamsPages.IMPRINT.overwrite({
}, },
}) })
const TERMS_AND_CONDITIONS = defaultPageParamsPages.TERMS_AND_CONDITIONS.overwrite({ const TERMS_AND_CONDITIONS = defaultPageParamsPages.TERMS_AND_CONDITIONS.overwrite({
// externalLink: null, // if string is defined and not empty it's dominating // externalLink: null, // if defined it's dominating
internalPage: { internalPage: {
// footerIdent: 'site.termsAndConditions', // localized string identifier, if undefined default is used // footerIdent: 'site.termsAndConditions', // localized string identifier, if undefined default is used
@ -57,7 +68,7 @@ const TERMS_AND_CONDITIONS = defaultPageParamsPages.TERMS_AND_CONDITIONS.overwri
}, },
}) })
const CODE_OF_CONDUCT = defaultPageParamsPages.CODE_OF_CONDUCT.overwrite({ const CODE_OF_CONDUCT = defaultPageParamsPages.CODE_OF_CONDUCT.overwrite({
// externalLink: null, // if string is defined and not empty it's dominating // externalLink: null, // if defined it's dominating
internalPage: { internalPage: {
// footerIdent: 'site.code-of-conduct', // localized string identifier, if undefined default is used // footerIdent: 'site.code-of-conduct', // localized string identifier, if undefined default is used
@ -70,7 +81,7 @@ const CODE_OF_CONDUCT = defaultPageParamsPages.CODE_OF_CONDUCT.overwrite({
}, },
}) })
const DATA_PRIVACY = defaultPageParamsPages.DATA_PRIVACY.overwrite({ const DATA_PRIVACY = defaultPageParamsPages.DATA_PRIVACY.overwrite({
// externalLink: null, // if string is defined and not empty it's dominating // externalLink: null, // if defined it's dominating
internalPage: { internalPage: {
// footerIdent: 'site.data-privacy', // localized string identifier, if undefined default is used // footerIdent: 'site.data-privacy', // localized string identifier, if undefined default is used
@ -83,7 +94,7 @@ const DATA_PRIVACY = defaultPageParamsPages.DATA_PRIVACY.overwrite({
}, },
}) })
const FAQ = defaultPageParamsPages.FAQ.overwrite({ const FAQ = defaultPageParamsPages.FAQ.overwrite({
// externalLink: null, // if string is defined and not empty it's dominating // externalLink: null, // if defined it's dominating
internalPage: { internalPage: {
// footerIdent: 'site.faq', // localized string identifier, if undefined default is used // footerIdent: 'site.faq', // localized string identifier, if undefined default is used
@ -96,7 +107,11 @@ const FAQ = defaultPageParamsPages.FAQ.overwrite({
}, },
}) })
const SUPPORT = defaultPageParamsPages.SUPPORT.overwrite({ const SUPPORT = defaultPageParamsPages.SUPPORT.overwrite({
externalLink: 'https://ocelot.social', // if string is defined and not empty it's dominating // if defined it's dominating
externalLink: {
url: 'https://ocelot.social',
target: '_blank',
},
internalPage: { internalPage: {
// footerIdent: 'site.support', // localized string identifier, if undefined default is used // footerIdent: 'site.support', // localized string identifier, if undefined default is used

View File

@ -16,10 +16,7 @@ export function internalPageMixins(pageParams) {
}, },
created() { created() {
if (!this.pageParams.isInternalPage) { if (!this.pageParams.isInternalPage) {
// to avoid possible errors, because 'window' is only defined on browser side but not in NodeJS on client side. check for 'typeof window' is neccessary, because if it's not defined at all you can't check for 'window !== undefined' without the same error 'window is undefined' this.pageParams.redirectToPage(this)
if (typeof window !== 'undefined') {
window.location.href = this.pageParams.externalLink
}
} }
}, },
} }