feat(webapp): post page group link improvement (#8883)

This commit is contained in:
Wolfgang Huß 2025-09-20 12:15:04 +02:00 committed by GitHub
parent de65a380ab
commit 2ed92c0a78
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 235 additions and 227 deletions

View File

@ -536,7 +536,7 @@
},
"description": "Beschreibung",
"editGroupSettings": {
"groupName": "Einstellungen für „{name}“",
"groupTitle": "Einstellungen für ",
"title": "Meine Gruppe ändern"
},
"errors": {
@ -829,23 +829,17 @@
"submitted": "Kommentar gesendet",
"updated": "Änderungen gespeichert"
},
"createNewEvent": {
"forGroup": {
"title": "Für die Gruppe „{name}“"
},
"title": "Erstelle eine Veranstaltung"
},
"createNewPost": {
"forGroup": {
"title": "Für die Gruppe „{name}“"
},
"createNewArticle": {
"title": "Erstelle einen Beitrag"
},
"createNewEvent": {
"title": "Erstelle eine Veranstaltung"
},
"edited": "bearbeitet",
"editPost": {
"event": "Bearbeite deine Veranstaltung",
"forGroup": {
"title": "Für die Gruppe „{name}“"
"title": "Für die Gruppe "
},
"title": "Bearbeite deinen Beitrag"
},
@ -881,7 +875,7 @@
},
"viewPost": {
"forGroup": {
"title": "In der Gruppe „{name}“"
"title": "In der Gruppe "
},
"title": "Beitrag"
}

View File

@ -536,7 +536,7 @@
},
"description": "Description",
"editGroupSettings": {
"groupName": "Settings Of “{name}”",
"groupTitle": "Settings of ",
"title": "Edit My Group"
},
"errors": {
@ -829,23 +829,17 @@
"submitted": "Comment submitted!",
"updated": "Changes saved!"
},
"createNewEvent": {
"forGroup": {
"title": "For The Group “{name}”"
},
"title": "Create an Event"
},
"createNewPost": {
"forGroup": {
"title": "For The Group “{name}”"
},
"createNewArticle": {
"title": "Create an Article"
},
"createNewEvent": {
"title": "Create an Event"
},
"edited": "edited",
"editPost": {
"event": "Edit Your Event",
"forGroup": {
"title": "For The Group “{name}”"
"title": "For The Group "
},
"title": "Edit Your Post"
},
@ -881,7 +875,7 @@
},
"viewPost": {
"forGroup": {
"title": "In The Group “{name}”"
"title": "In The Group "
},
"title": "Post"
}

View File

@ -536,7 +536,7 @@
},
"description": null,
"editGroupSettings": {
"groupName": null,
"groupTitle": null,
"title": null
},
"errors": {
@ -829,13 +829,10 @@
"submitted": "Comentario enviado",
"updated": "Cambios guardados"
},
"createNewEvent": {
"forGroup": {
"title": null
},
"createNewArticle": {
"title": null
},
"createNewPost": {
"createNewEvent": {
"forGroup": {
"title": null
},

View File

@ -536,7 +536,7 @@
},
"description": null,
"editGroupSettings": {
"groupName": null,
"groupTitle": null,
"title": null
},
"errors": {
@ -829,13 +829,10 @@
"submitted": "Commentaire soumis",
"updated": "Changements sauvegardés"
},
"createNewEvent": {
"forGroup": {
"title": null
},
"createNewArticle": {
"title": null
},
"createNewPost": {
"createNewEvent": {
"forGroup": {
"title": null
},

View File

@ -536,7 +536,7 @@
},
"description": null,
"editGroupSettings": {
"groupName": null,
"groupTitle": null,
"title": null
},
"errors": {
@ -829,13 +829,10 @@
"submitted": null,
"updated": null
},
"createNewEvent": {
"forGroup": {
"title": null
},
"createNewArticle": {
"title": null
},
"createNewPost": {
"createNewEvent": {
"forGroup": {
"title": null
},

View File

@ -536,7 +536,7 @@
},
"description": null,
"editGroupSettings": {
"groupName": null,
"groupTitle": null,
"title": null
},
"errors": {
@ -829,13 +829,10 @@
"submitted": null,
"updated": null
},
"createNewEvent": {
"forGroup": {
"title": null
},
"createNewArticle": {
"title": null
},
"createNewPost": {
"createNewEvent": {
"forGroup": {
"title": null
},

View File

@ -536,7 +536,7 @@
},
"description": null,
"editGroupSettings": {
"groupName": null,
"groupTitle": null,
"title": null
},
"errors": {
@ -829,13 +829,10 @@
"submitted": "Komentarz dodany",
"updated": null
},
"createNewEvent": {
"forGroup": {
"title": null
},
"createNewArticle": {
"title": null
},
"createNewPost": {
"createNewEvent": {
"forGroup": {
"title": null
},

View File

@ -536,7 +536,7 @@
},
"description": null,
"editGroupSettings": {
"groupName": null,
"groupTitle": null,
"title": null
},
"errors": {
@ -829,13 +829,10 @@
"submitted": "Comentário Enviado",
"updated": "Alterações salvas"
},
"createNewEvent": {
"forGroup": {
"title": null
},
"createNewArticle": {
"title": null
},
"createNewPost": {
"createNewEvent": {
"forGroup": {
"title": null
},

View File

@ -536,7 +536,7 @@
},
"description": null,
"editGroupSettings": {
"groupName": null,
"groupTitle": null,
"title": null
},
"errors": {
@ -829,13 +829,10 @@
"submitted": "Комментарий отправлен",
"updated": "Изменения сохраненные"
},
"createNewEvent": {
"forGroup": {
"title": null
},
"createNewArticle": {
"title": null
},
"createNewPost": {
"createNewEvent": {
"forGroup": {
"title": null
},

View File

@ -206,7 +206,12 @@
</base-card>
</ds-space>
<ds-space v-if="isGroupMemberNonePending" centered>
<nuxt-link :to="{ name: 'post-create', query: { groupId: group.id } }">
<nuxt-link
:to="{
name: 'post-create-type',
query: { groupId: group.id },
}"
>
<base-button
class="profile-post-add-button"
icon="plus"

View File

@ -3,7 +3,10 @@
<ds-space margin="small">
<ds-heading tag="h1">{{ $t('group.editGroupSettings.title') }}</ds-heading>
<ds-heading tag="h2">
{{ $t('group.editGroupSettings.groupName', { name: group.name }) }}
{{ $t('group.editGroupSettings.groupTitle') }}
<nuxt-link :to="{ name: 'groups-id-slug', params: { slug: group.slug, id: group.id } }">
{{ group.name }}
</nuxt-link>
</ds-heading>
</ds-space>
<ds-space margin="large" />
@ -25,6 +28,11 @@ import { groupQuery } from '~/graphql/groups.js'
import { mapGetters } from 'vuex'
export default {
data() {
return {
group: {},
}
},
computed: {
...mapGetters({
user: 'auth/user',
@ -46,11 +54,6 @@ export default {
]
},
},
data() {
return {
group: {},
}
},
async asyncData(context) {
const {
app,
@ -78,3 +81,9 @@ export default {
},
}
</script>
<style lang="scss" scoped>
.ds-heading {
margin-top: 0;
}
</style>

View File

@ -3,7 +3,7 @@
<!-- create post -->
<div :class="POST_ADD_BUTTON_POSITION_TOP ? 'box-add-button-top' : ''">
<client-only>
<nuxt-link :to="{ name: 'post-create' }" :class="{ 'hide-filter': hideByScroll }">
<nuxt-link :to="{ name: 'post-create-type' }" :class="{ 'hide-filter': hideByScroll }">
<base-button
v-tooltip="{
content: $t('contribution.newPost'),

View File

@ -3,8 +3,13 @@
<div>
<ds-space margin="small">
<ds-heading tag="h1">{{ heading }}</ds-heading>
<ds-heading v-if="post && post.group" tag="h2">
{{ $t('post.viewPost.forGroup.title', { name: post.group.name }) }}
<ds-heading v-if="post && post.group && post.group.id && post.group.slug" tag="h2">
{{ $t('post.viewPost.forGroup.title') }}
<nuxt-link
:to="{ name: 'groups-id-slug', params: { slug: post.group.slug, id: post.group.id } }"
>
{{ post.group.name }}
</nuxt-link>
</ds-heading>
</ds-space>
<ds-space margin="large" />
@ -451,4 +456,8 @@ export default {
margin-top: $space-small;
margin-bottom: calc($space-base * 2);
}
.ds-heading {
margin-top: 0;
}
</style>

View File

@ -1,137 +0,0 @@
<template>
<div>
<ds-flex gutter="small">
<ds-flex-item :width="{ base: '100%', md: '200px' }">
<ds-menu class="post-type-menu" :routes="routes">
<ds-menu-item
@click.prevent="switchPostType($event, item)"
slot="menuitem"
slot-scope="item"
:route="item.route"
class="post-type-menu-item"
>
{{ item.route.name }}
</ds-menu-item>
</ds-menu>
</ds-flex-item>
<ds-flex-item :width="{ base: '100%', md: 1 }">
<transition name="slide-up" appear>
<div>
<div>
<h1 v-if="!createEvent" class="title">
{{ $t('post.createNewPost.title') }}
</h1>
<h1 v-else class="title">
{{ $t('post.createNewEvent.title') }}
</h1>
</div>
<contribution-form :group="group" :createEvent="createEvent" />
</div>
</transition>
</ds-flex-item>
</ds-flex>
</div>
</template>
<script>
import { groupQuery } from '~/graphql/groups'
import ContributionForm from '~/components/ContributionForm/ContributionForm'
export default {
components: {
ContributionForm,
},
data() {
const { groupId = null } = this.$route.query
return {
groupId,
createEvent: false,
}
},
computed: {
group() {
return this.Group && this.Group[0] ? this.Group[0] : null
},
routes() {
return [
{
name: this.$t('post.name'),
path: `/post/create`,
type: 'post',
},
{
name: this.$t('post.event'),
path: `/`,
type: 'event',
},
]
},
},
apollo: {
Group: {
query() {
return groupQuery(this.$i18n)
},
variables() {
return {
id: this.groupId,
// followedByCount: this.followedByCount,
// followingCount: this.followingCount,
}
},
skip() {
return !this.groupId
},
error(error) {
this.$toast.error(error.message)
},
fetchPolicy: 'cache-and-network',
},
},
methods: {
switchPostType(event, route) {
if (route.route.type.toLowerCase() === 'event') {
this.createEvent = true
} else {
this.createEvent = false
}
// hacky way to set active element
const menuItems = document.querySelectorAll('.post-type-menu-item')
menuItems.forEach((menuItem) => {
menuItem.firstChild.classList.remove('router-link-exact-active', 'router-link-active')
})
event.target.classList.add('router-link-exact-active')
},
},
}
</script>
<style lang="scss">
.inactive-tab-button {
background-color: #ff000000 !important;
color: 'whitesmoke' !important;
}
.group-create-title {
font-size: 30px;
text-align: center;
}
// copy hover effect from ghost button to use for ds-card
.create-form-btn:not(.ds-card-primary):hover {
background-color: #faf9fa;
}
.create-form-btn .ds-button-ghost:hover {
background-color: transparent;
}
.menu-item-active {
color: $color-primary;
border-left: 2px solid $color-primary;
background-color: #faf9fa;
}
@media screen and (min-width: 768px) {
.post-type-menu {
margin-top: 39px;
}
}
</style>

View File

@ -1,5 +1,5 @@
import { mount } from '@vue/test-utils'
import create from './create.vue'
import create from './_type.vue'
import Vuex from 'vuex'
const localVue = global.localVue
@ -10,6 +10,9 @@ describe('create.vue', () => {
const mocks = {
$t: jest.fn(),
$route: {
params: {
type: 'article',
},
query: {
groupId: null,
},

View File

@ -0,0 +1,135 @@
<template>
<div>
<ds-space margin="small">
<ds-heading tag="h1">
{{ heading }}
</ds-heading>
<ds-heading v-if="group && group.id && group.slug" tag="h2">
{{ $t('post.viewPost.forGroup.title') }}
<nuxt-link :to="{ name: 'groups-id-slug', params: { slug: group.slug, id: group.id } }">
{{ group.name }}
</nuxt-link>
</ds-heading>
</ds-space>
<ds-space margin="large" />
<ds-flex gutter="small">
<ds-flex-item :width="{ base: '100%', md: '200px' }">
<ds-menu :routes="routes">
<ds-menu-item
@click.prevent="switchPostType($event, item)"
slot="menuitem"
slot-scope="item"
:route="item.route"
>
{{ item.route.name }}
</ds-menu-item>
</ds-menu>
</ds-flex-item>
<ds-flex-item :width="{ base: '100%', md: 1 }">
<transition name="slide-up" appear>
<contribution-form :group="group" :createEvent="createEvent" />
</transition>
</ds-flex-item>
</ds-flex>
</div>
</template>
<script>
import { groupQuery } from '~/graphql/groups'
import ContributionForm from '~/components/ContributionForm/ContributionForm'
export default {
components: {
ContributionForm,
},
data() {
const { groupId = null } = this.$route.query
const { type } = this.$route.params
if (groupId) this.$router.replace(`/post/create/${type}`) // remove query so that the route hits one of the menu paths
return {
groupId,
type,
}
},
async asyncData({ route, redirect }) {
// http://localhost:3000/post/create/type
// http://localhost:3000/post/create/type?groupId=id
const {
params: { type },
query: { groupId },
} = route
if (!['article', 'event'].includes(type)) {
const defaultType = 'article'
let path = `/post/create/${defaultType}`
if (groupId) path += `?groupId=${groupId}`
redirect(path)
}
},
computed: {
group() {
return this.Group && this.Group[0] ? this.Group[0] : null
},
heading() {
return !this.createEvent
? this.$t('post.createNewArticle.title')
: this.$t('post.createNewEvent.title')
},
routes() {
return [
{
name: this.$t('post.name'),
path: `/post/create/article`,
type: 'article',
},
{
name: this.$t('post.event'),
path: `/post/create/event`,
type: 'event',
},
]
},
createEvent() {
return this.type === 'event'
},
},
apollo: {
Group: {
query() {
return groupQuery(this.$i18n)
},
variables() {
return {
id: this.groupId,
}
},
skip() {
return !this.groupId
},
error(error) {
this.$toast.error(error.message)
},
fetchPolicy: 'cache-and-network',
},
},
methods: {
switchPostType(_event, route) {
const { type: oldType } = this.$route.params
const newType = route.route.type.toLowerCase()
if (newType !== oldType) {
this.type = newType
if (this.groupId) {
this.$router.replace(`/post/create/${this.type}/?groupId=${this.groupId}`)
} else {
this.$router.replace(`/post/create/${this.type}`)
}
}
},
},
}
</script>
<style lang="scss" scoped>
.ds-heading {
margin-top: 0;
}
</style>

View File

@ -2,14 +2,23 @@
<div>
<ds-space margin="small">
<ds-heading tag="h1">
{{
contribution && contribution.postType[0] === 'Event'
? $t('post.editPost.event')
: $t('post.editPost.title')
}}
{{ heading }}
</ds-heading>
<ds-heading v-if="contribution && contribution.group" tag="h2">
{{ $t('post.editPost.forGroup.title', { name: contribution.group.name }) }}
<ds-heading
v-if="
contribution && contribution.group && contribution.group.id && contribution.group.slug
"
tag="h2"
>
{{ $t('post.editPost.forGroup.title') }}
<nuxt-link
:to="{
name: 'groups-id-slug',
params: { slug: contribution.group.slug, id: contribution.group.id },
}"
>
{{ contribution.group.name }}
</nuxt-link>
</ds-heading>
</ds-space>
<ds-space margin="large" />
@ -39,6 +48,11 @@ export default {
...mapGetters({
user: 'auth/user',
}),
heading() {
return this.contribution && this.contribution.postType[0] === 'Event'
? this.$t('post.editPost.event')
: this.$t('post.editPost.title')
},
},
data() {
return {
@ -70,3 +84,9 @@ export default {
},
}
</script>
<style lang="scss" scoped>
.ds-heading {
margin-top: 0;
}
</style>

View File

@ -1727,7 +1727,6 @@ exports[`ProfileSlug given an authenticated user given the logged in user as pro
<button
class="profile-post-add-button base-button --icon-only --circle --filled has-tooltip"
data-original-title="null"
path="[object Object]"
type="button"
>
<span
@ -2332,7 +2331,6 @@ exports[`ProfileSlug given an authenticated user given the logged in user as pro
<button
class="profile-post-add-button base-button --icon-only --circle --filled has-tooltip"
data-original-title="null"
path="[object Object]"
type="button"
>
<span

View File

@ -127,14 +127,13 @@
<!-- feed -->
<ds-grid-item :row-span="2" column-span="fullWidth">
<ds-space centered>
<nuxt-link :to="{ name: 'post-create' }">
<nuxt-link :to="{ name: 'post-create-type' }">
<base-button
v-if="myProfile"
v-tooltip="{
content: $t('contribution.newPost'),
placement: 'left',
}"
:path="{ name: 'post-create' }"
class="profile-post-add-button"
icon="plus"
circle