Merge branch '5059-epic-groups' of github.com:Ocelot-Social-Community/Ocelot-Social into 5059-groups/5501-add-group-link-to-posts-in-webapp

This commit is contained in:
Wolfgang Huß 2022-10-19 13:36:46 +02:00
commit 2eb5995116
9 changed files with 418 additions and 185 deletions

View File

@ -360,6 +360,33 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
}),
])
// post into group
await Promise.all([
mutate({
mutation: createPostMutation(),
variables: {
id: 'p0-g0',
groupId: 'g0',
title: `What happend in Shanghai?`,
content: 'A sack of rise dropped in Shanghai. Should we further investigate?',
categoryIds: ['cat6'],
},
}),
])
authenticatedUser = await bobDerBaumeister.toJson()
await Promise.all([
mutate({
mutation: createPostMutation(),
variables: {
id: 'p1-g0',
groupId: 'g0',
title: `The man on the moon`,
content: 'We have to further investigate about the stories of a man living on the moon.',
categoryIds: ['cat12', 'cat16'],
},
}),
])
authenticatedUser = await jennyRostock.toJson()
await Promise.all([
mutate({
@ -439,6 +466,32 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
},
}),
])
// post into group
await Promise.all([
mutate({
mutation: createPostMutation(),
variables: {
id: 'p0-g1',
groupId: 'g1',
title: `Can we use ocelot for education?`,
content: 'I like the concept of this school. Can we use our software in this?',
categoryIds: ['cat8'],
},
}),
])
authenticatedUser = await peterLustig.toJson()
await Promise.all([
mutate({
mutation: createPostMutation(),
variables: {
id: 'p1-g1',
groupId: 'g1',
title: `Can we push this idea out of France?`,
content: 'This idea is too inportant to have the scope only on France.',
categoryIds: ['cat14'],
},
}),
])
authenticatedUser = await bobDerBaumeister.toJson()
await Promise.all([
@ -527,6 +580,20 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
}),
])
authenticatedUser = await louie.toJson()
await Promise.all([
mutate({
mutation: createPostMutation(),
variables: {
id: 'p0-g2',
groupId: 'g2',
title: `I am a Noob`,
content: 'I am new to Yoga and did not join this group so far.',
categoryIds: ['cat4'],
},
}),
])
// Create Posts
const [p0, p1, p3, p4, p5, p6, p9, p10, p11, p13, p14, p15] = await Promise.all([

View File

@ -7,7 +7,6 @@
icon="ellipsis-v"
size="small"
circle
ghost
@click.prevent="toggleMenu()"
/>
</slot>

View File

@ -1,9 +1,12 @@
import { mount } from '@vue/test-utils'
import { config, mount } from '@vue/test-utils'
import GroupContentMenu from './GroupContentMenu.vue'
const localVue = global.localVue
config.stubs['router-link'] = '<span><slot /></span>'
const propsData = {
usage: 'groupTeaser',
resource: {},
group: {},
resourceType: 'group',
@ -29,7 +32,7 @@ describe('GroupContentMenu', () => {
})
it('renders', () => {
expect(wrapper.findAll('.group-menu')).toHaveLength(1)
expect(wrapper.findAll('.group-content-menu')).toHaveLength(1)
})
})
})

View File

@ -1,5 +1,5 @@
<template>
<dropdown class="group-menu" :placement="placement" offset="5">
<dropdown class="group-content-menu" :placement="placement" offset="5">
<template #default="{ toggleMenu }">
<slot name="button" :toggleMenu="toggleMenu">
<base-button
@ -40,35 +40,34 @@ export default {
Dropdown,
},
props: {
placement: { type: String, default: 'bottom-end' },
resource: { type: Object, required: true },
group: { type: Object, required: true },
resourceType: {
usage: {
type: String,
required: true,
validator: (value) => {
return value.match(/(group)/)
return value.match(/(groupTeaser|groupProfile)/)
},
},
group: { type: Object, required: true },
placement: { type: String, default: 'bottom-end' },
},
computed: {
routes() {
const routes = []
if (this.resourceType === 'group') {
if (this.usage !== 'groupProfile') {
routes.push({
label: this.$t('group.contentMenu.visitGroupPage'),
icon: 'home',
name: 'group-id-slug',
params: { id: this.group.id, slug: this.group.slug },
})
if (this.group.myRole === 'owner') {
routes.push({
label: this.$t('admin.settings.name'),
path: `/group/edit/${this.resource.id}`,
icon: 'edit',
})
}
}
if (this.group.myRole === 'owner') {
routes.push({
label: this.$t('admin.settings.name'),
path: `/group/edit/${this.group.id}`,
icon: 'edit',
})
}
return routes

View File

@ -7,79 +7,97 @@
:schema="formSchema"
@submit="submit"
>
<ds-input
:label="$t('group.name')"
v-model="formData.name"
:placeholder="`${$t('group.name')} …`"
></ds-input>
<ds-input
v-if="update"
:label="$t('group.labelSlug')"
v-model="formData.slug"
icon="at"
:placeholder="`${$t('group.labelSlug')} …`"
></ds-input>
<!-- groupType -->
<!-- TODO: change it has to be implemented later -->
<!-- TODO: move 'ds-select' from styleguide to main code and implement missen translation etc. functionality -->
<!-- <ds-select
id="groupType"
:label="$t('group.type')"
:v-model="formData.groupType"
:label-prop="'label'"
:options="groupTypeOptions"
icon="user"
:placeholder="$t('group.type') + ' …'"
></ds-select> -->
<ds-text class="select-label">
{{ $t('group.type') }}
</ds-text>
<ds-icon class="select-icon" name="user" />
<select
class="select"
:options="groupTypeOptions"
:value="formData.groupType"
:disabled="update"
@change="changeGroupType($event)"
>
<option v-for="groupType in groupTypeOptions" :key="groupType" :value="groupType">
{{ $t(`group.types.${groupType}`) }}
</option>
</select>
<!-- goal -->
<ds-input
:label="$t('group.goal')"
v-model="formData.about"
:placeholder="$t('group.goal') + ' …'"
rows="3"
></ds-input>
<!-- description -->
<ds-input
:label="$t('group.description')"
v-model="formData.description"
:placeholder="$t('group.description') + ' …'"
type="textarea"
rows="3"
></ds-input>
<ds-space margin-top="large">
<!-- "errors" is only working if you use a submit event on the form -->
<template #default="{ errors }">
<!-- group Name -->
<ds-input
name="name"
:label="$t('group.name')"
model="name"
autofocus
:placeholder="`${$t('group.name')} …`"
/>
<ds-chip size="base" :color="errors && errors.name ? 'danger' : 'medium'">
{{ `${formData.name.length} / ${formSchema.name.min}${formSchema.name.max}` }}
<base-icon v-if="errors && errors.name" name="warning" />
</ds-chip>
<!-- group Slug -->
<ds-input
v-if="update"
:label="$t('group.labelSlug')"
model="slug"
icon="at"
:placeholder="`${$t('group.labelSlug')} …`"
></ds-input>
<ds-space v-if="update" margin-top="small" />
<!-- groupType -->
<ds-text class="select-label">
{{ $t('group.type') }}
</ds-text>
<!-- TODO: change it has to be implemented later -->
<!-- TODO: move 'ds-select' from style guide to main code and implement missing translation etc. functionality -->
<select
class="select ds-input appearance--auto"
name="groupType"
model="groupType"
:value="formData.groupType"
:disabled="update"
@change="changeGroupType($event)"
>
<option v-for="groupType in groupTypeOptions" :key="groupType" :value="groupType">
{{ $t(`group.types.${groupType}`) }}
</option>
</select>
<ds-chip
size="base"
:color="errors && errors.groupType && formData.groupType === '' ? 'danger' : 'medium'"
>
{{ `${formData.groupType === '' ? 0 : 1} / 1` }}
<base-icon
v-if="errors && errors.groupType && formData.groupType === ''"
name="warning"
/>
</ds-chip>
<!-- goal -->
<ds-input
name="about"
:label="$t('group.goal')"
v-model="formData.about"
:placeholder="$t('group.goal') + ' …'"
rows="3"
/>
<ds-space margin-top="small" />
<!-- description -->
<ds-text class="select-label">
{{ $t('group.description') }}
</ds-text>
<editor
name="description"
model="description"
:users="null"
:value="formData.description"
:hashtags="null"
@input="updateEditorDescription"
/>
<ds-chip size="base" :color="errors && errors.description ? 'danger' : 'medium'">
{{ `${descriptionLength} / ${formSchema.description.min}` }}
<base-icon v-if="errors && errors.description" name="warning" />
</ds-chip>
<!-- actionRadius -->
<!-- TODO: move 'ds-select' from styleguide to main code and implement missen translation etc. functionality -->
<!-- <ds-select
id="actionRadius"
:label="$t('group.actionRadius')"
v-model="formData"
model="actionRadius"
:options="['regional', 'national', 'continental', 'global']"
icon="globe"
:placeholder="`${$t('group.actionRadius')} …`"
></ds-select> -->
<ds-text class="select-label">
{{ $t('group.actionRadius') }}
</ds-text>
<ds-icon class="select-icon" name="globe" />
<!-- TODO: move 'ds-select' from styleguide to main code and implement missing translation etc. functionality -->
<select
class="select"
:options="actionRadiusOptions"
class="select ds-input appearance--auto"
name="actionRadius"
:value="formData.actionRadius"
@change="changeActionRadius($event)"
>
@ -91,41 +109,68 @@
{{ $t(`group.actionRadii.${actionRadius}`) }}
</option>
</select>
<ds-chip
size="base"
:color="
errors && errors.actionRadius && formData.actionRadius === '' ? 'danger' : 'medium'
"
>
{{ `${formData.actionRadius === '' ? 0 : 1} / 1` }}
<base-icon
v-if="errors && errors.actionRadius && formData.actionRadius === ''"
name="warning"
/>
</ds-chip>
<!-- location -->
<ds-select
id="city"
:label="$t('settings.data.labelCity')"
:label="$t('settings.data.labelCity') + locationNameLabelAddOnOldName"
v-model="formData.locationName"
:options="cities"
icon="map-marker"
:icon-right="null"
:placeholder="$t('settings.data.labelCity') + ' …'"
:loading="loadingGeo"
@input.native="handleCityInput"
/>
<!-- TODO: implement clear button -->
<!-- <base-button icon="close" circle ghost size="small" :disabled="formData.locationName.length === 0" @click="clear" /> -->
</ds-space>
<ds-space margin-top="large">
<base-button
v-if="formLocationName !== ''"
icon="close"
ghost
size="small"
style="position: relative; display: inline-block; right: -96%; top: -33px; width: 26px"
@click="formData.locationName = ''"
></base-button>
<ds-space margin-top="small" />
<!-- category -->
<categories-select
v-if="categoriesActive"
model="categoryIds"
name="categoryIds"
:existingCategoryIds="formData.categoryIds"
/>
</ds-space>
<ds-space margin-top="large">
<nuxt-link to="/my-groups">
<ds-button>{{ $t('actions.cancel') }}</ds-button>
</nuxt-link>
<ds-button
type="submit"
icon="save"
:disabled="update ? submitDisableEdit : submitDisable"
primary
@click.prevent="submit()"
<ds-chip
v-if="categoriesActive"
size="base"
:color="errors && errors.categoryIds ? 'danger' : 'medium'"
>
{{ update ? $t('group.update') : $t('group.save') }}
</ds-button>
</ds-space>
{{ formData.categoryIds.length }} / 3
<base-icon v-if="errors && errors.categoryIds" name="warning" />
</ds-chip>
<!-- submit -->
<ds-space margin-top="large">
<nuxt-link to="/my-groups">
<ds-button>{{ $t('actions.cancel') }}</ds-button>
</nuxt-link>
<ds-button type="submit" icon="save" primary :disabled="checkFormError(errors)" fill>
{{ update ? $t('group.update') : $t('group.save') }}
</ds-button>
</ds-space>
</template>
</ds-form>
</div>
</template>
@ -133,7 +178,12 @@
<script>
import CategoriesSelect from '~/components/CategoriesSelect/CategoriesSelect'
import { CATEGORIES_MIN, CATEGORIES_MAX } from '~/constants/categories.js'
import { NAME_LENGTH_MIN, NAME_LENGTH_MAX } from '~/constants/groups.js'
import {
NAME_LENGTH_MIN,
NAME_LENGTH_MAX,
DESCRIPTION_WITHOUT_HTML_LENGTH_MIN,
} from '~/constants/groups.js'
import Editor from '~/components/Editor/Editor'
import { queryLocations } from '~/graphql/location'
let timeout
@ -142,6 +192,7 @@ export default {
name: 'GroupForm',
components: {
CategoriesSelect,
Editor,
},
props: {
update: {
@ -171,17 +222,33 @@ export default {
groupType: groupType || '',
about: about || '',
description: description || '',
// from database 'locationName' comes as "string | null"
// 'formData.locationName':
// see 'created': tries to set it to a "requestGeoData" object and fills the menu if possible
// if user selects one from menu we get a "requestGeoData" object here
// "requestGeoData" object: "{ id: String, label: String, value: String }"
// otherwise it's a string: empty or none empty
locationName: locationName || '',
actionRadius: actionRadius || '',
categoryIds: categories ? categories.map((category) => category.id) : [],
},
formSchema: {
name: { required: true, min: NAME_LENGTH_MIN, max: NAME_LENGTH_MAX },
slug: { required: false },
groupType: { required: true },
about: { required: true },
description: { required: true },
actionRadius: { required: true },
slug: { required: false, min: NAME_LENGTH_MIN },
groupType: { required: true, min: 1 },
about: { required: false },
description: {
type: 'string',
required: true,
min: DESCRIPTION_WITHOUT_HTML_LENGTH_MIN,
validator: (_, value = '') => {
if (this.$filters.removeHtml(value).length < this.formSchema.description.min) {
return [new Error()]
}
return []
},
},
actionRadius: { required: true, min: 1 },
locationName: { required: false },
categoryIds: {
type: 'array',
@ -199,46 +266,74 @@ export default {
},
}
},
async created() {
// set to "requestGeoData" object and fill select menu if possible
this.formData.locationName =
(await this.requestGeoData(this.formLocationName)) || this.formLocationName
},
computed: {
submitDisable() {
return (
this.formData.name === '' ||
this.formData.groupType === '' ||
// this.formData.about === '' || // not mandatory
this.formData.description === '' ||
this.formData.actionRadius === '' ||
// this.formData.locationName === '' || // not mandatory
this.formData.categoryIds.length === 0
)
formLocationName() {
const isNestedValue =
typeof this.formData.locationName === 'object' &&
typeof this.formData.locationName.value === 'string'
const isDirectString = typeof this.formData.locationName === 'string'
return isNestedValue
? this.formData.locationName.value
: isDirectString
? this.formData.locationName
: ''
},
submitDisableEdit() {
locationNameLabelAddOnOldName() {
return this.formLocationName !== '' ? ' — ' + this.formLocationName : ''
},
descriptionLength() {
return this.$filters.removeHtml(this.formData.description).length
},
sameLocation() {
const dbLocationName = this.group.locationName || ''
return dbLocationName === this.formLocationName
},
sameCategories() {
if (this.group.categories.length !== this.formData.categoryIds.length) return false
const groupCategories = []
this.group.categories.forEach((categories) => {
groupCategories.push(categories.id)
const some = this.formData.categoryIds.some((item) => item === categories.id)
if (!some) return false
})
return true
},
disableButtonByUpdate() {
if (!this.update) return true
return (
this.formData.name === this.group.name &&
this.formData.slug === this.group.slug &&
// this.formData.groupType === this.group.groupType && // can not be changed for now
this.formData.about === this.group.about &&
this.formData.description === this.group.description &&
this.formData.actionRadius === this.group.actionRadius &&
this.formData.locationName === (this.group.locationName ? this.group.locationName : '') &&
this.group.name === this.formData.name &&
this.group.slug === this.formData.slug &&
this.group.about === this.formData.about &&
this.group.description === this.formData.description &&
this.group.actionRadius === this.formData.actionRadius &&
this.sameLocation &&
this.sameCategories
)
},
sameCategories() {
const formDataCategories = this.formData.categoryIds.map((id) => id).sort()
const groupDataCategories = this.group.categories.map((category) => category.id).sort()
let equal = true
if (formDataCategories.length !== groupDataCategories.length) return false
formDataCategories.forEach((id, index) => {
equal = equal && id === groupDataCategories[index]
})
return equal
},
},
methods: {
checkFormError(error) {
if (!this.update && error && !!error && this.disableButtonByUpdate) return true
if (this.update && !error && this.disableButtonByUpdate) return true
return false
},
changeGroupType(event) {
this.formData.groupType = event.target.value
},
changeActionRadius(event) {
this.formData.actionRadius = event.target.value
},
updateEditorDescription(value) {
this.$refs.groupForm.update('description', value)
},
submit() {
const { name, about, description, groupType, actionRadius, locationName, categoryIds } =
const { name, about, description, groupType, actionRadius, /* locationName, */ categoryIds } =
this.formData
const variables = {
name,
@ -246,7 +341,7 @@ export default {
description,
groupType,
actionRadius,
locationName: locationName.label,
locationName: this.formLocationName,
categoryIds,
}
this.update
@ -256,15 +351,12 @@ export default {
})
: this.$emit('createGroup', variables)
},
changeGroupType(event) {
this.formData.groupType = event.target.value
},
changeActionRadius(event) {
this.formData.actionRadius = event.target.value
},
handleCityInput(value) {
handleCityInput(event) {
clearTimeout(timeout)
timeout = setTimeout(() => this.requestGeoData(value), 500)
timeout = setTimeout(
() => this.requestGeoData(event.target ? event.target.value.trim() : ''),
500,
)
},
processLocationsResult(places) {
if (!places.length) {
@ -281,8 +373,7 @@ export default {
return result
},
async requestGeoData(e) {
const value = e.target ? e.target.value.trim() : ''
async requestGeoData(value) {
if (value === '') {
this.cities = []
return
@ -293,27 +384,57 @@ export default {
const lang = this.$i18n.locale()
const {
data: { queryLocations: res },
data: { queryLocations: result },
} = await this.$apollo.query({ query: queryLocations(), variables: { place, lang } })
this.cities = this.processLocationsResult(res)
this.cities = this.processLocationsResult(result)
this.loadingGeo = false
return this.cities.find((city) => city.value === value)
},
},
}
</script>
<style lang="scss" scoped>
<style lang="scss">
.appearance--auto {
-webkit-appearance: auto;
-moz-appearance: auto;
appearance: auto;
}
.select-label {
margin-bottom: 3pt;
color: $text-color-soft;
margin-bottom: 0;
padding-bottom: 4px;
color: #70677e;
font-size: 1rem;
}
.select-icon {
margin-right: 4pt;
color: $text-color-disabled;
.textarea-label {
padding-bottom: 14px;
}
.select {
margin-bottom: $space-small;
color: $text-color-base;
.group-form {
display: flex;
flex-direction: column;
> .ds-form-item {
margin: 0;
}
> .ds-chip {
align-self: flex-end;
margin: $space-xx-small 0 $space-base;
cursor: default;
}
> .select-field {
align-self: flex-end;
}
> .buttons {
align-self: flex-end;
margin-top: $space-base;
}
}
</style>

View File

@ -58,7 +58,7 @@
<div v-else class="categories-placeholder"></div>
<!-- group context menu -->
<client-only>
<group-content-menu resource-type="group" :resource="group" :group="group" />
<group-content-menu :usage="'groupTeaser'" :group="group || {}" placement="bottom-end" />
</client-only>
</footer>
<footer class="footer">
@ -78,7 +78,7 @@
<script>
import Category from '~/components/Category'
import GroupContentMenu from '~/components/Group/GroupContentMenu'
import GroupContentMenu from '~/components/ContentMenu/GroupContentMenu'
export default {
name: 'GroupTeaser',

View File

@ -6,7 +6,7 @@ const localVue = global.localVue
localVue.filter('date', (d) => d)
config.stubs['client-only'] = '<span><slot /></span>'
// config.stubs['v-popover'] = '<span><slot /></span>'
config.stubs['v-popover'] = '<span><slot /></span>'
config.stubs['nuxt-link'] = '<span><slot /></span>'
// config.stubs['infinite-loading'] = '<span><slot /></span>'
// config.stubs['follow-list'] = '<span><slot /></span>'
@ -237,6 +237,10 @@ describe('GroupProfileSlug', () => {
expect(wrapper.find('.profile-avatar').exists()).toBe(true)
})
it('has GroupContentMenu', () => {
expect(wrapper.find('.group-content-menu').exists()).toBe(true)
})
it('has group slug', () => {
expect(wrapper.find('[data-test="at"]').exists()).toBe(true)
expect(wrapper.text()).toContain('yoga-practice')
@ -385,6 +389,10 @@ describe('GroupProfileSlug', () => {
expect(wrapper.find('.profile-avatar').exists()).toBe(true)
})
it('has not(!) GroupContentMenu', () => {
expect(wrapper.find('.group-content-menu').exists()).toBe(false)
})
it('has group slug', () => {
expect(wrapper.find('[data-test="at"]').exists()).toBe(true)
expect(wrapper.text()).toContain('yoga-practice')
@ -493,6 +501,10 @@ describe('GroupProfileSlug', () => {
expect(wrapper.find('.profile-avatar').exists()).toBe(true)
})
it('has not(!) GroupContentMenu', () => {
expect(wrapper.find('.group-content-menu').exists()).toBe(false)
})
it('has group slug', () => {
expect(wrapper.find('[data-test="at"]').exists()).toBe(true)
expect(wrapper.text()).toContain('yoga-practice')
@ -601,6 +613,10 @@ describe('GroupProfileSlug', () => {
expect(wrapper.find('.profile-avatar').exists()).toBe(true)
})
it('has not(!) GroupContentMenu', () => {
expect(wrapper.find('.group-content-menu').exists()).toBe(false)
})
it('has group slug', () => {
expect(wrapper.find('[data-test="at"]').exists()).toBe(true)
expect(wrapper.text()).toContain('yoga-practice')
@ -713,6 +729,10 @@ describe('GroupProfileSlug', () => {
expect(wrapper.find('.profile-avatar').exists()).toBe(true)
})
it('has GroupContentMenu', () => {
expect(wrapper.find('.group-content-menu').exists()).toBe(true)
})
it('has group slug', () => {
expect(wrapper.find('[data-test="at"]').exists()).toBe(true)
expect(wrapper.text()).toContain('school-for-citizens')
@ -825,6 +845,10 @@ describe('GroupProfileSlug', () => {
expect(wrapper.find('.profile-avatar').exists()).toBe(true)
})
it('has not(!) GroupContentMenu', () => {
expect(wrapper.find('.group-content-menu').exists()).toBe(false)
})
it('has group slug', () => {
expect(wrapper.find('[data-test="at"]').exists()).toBe(true)
expect(wrapper.text()).toContain('school-for-citizens')
@ -937,6 +961,10 @@ describe('GroupProfileSlug', () => {
expect(wrapper.find('.profile-avatar').exists()).toBe(true)
})
it('has not(!) GroupContentMenu', () => {
expect(wrapper.find('.group-content-menu').exists()).toBe(false)
})
it('has group slug', () => {
expect(wrapper.find('[data-test="at"]').exists()).toBe(true)
expect(wrapper.text()).toContain('school-for-citizens')
@ -1049,6 +1077,10 @@ describe('GroupProfileSlug', () => {
expect(wrapper.find('.profile-avatar').exists()).toBe(true)
})
it('has not(!) GroupContentMenu', () => {
expect(wrapper.find('.group-content-menu').exists()).toBe(false)
})
it('has group slug', () => {
expect(wrapper.find('[data-test="at"]').exists()).toBe(true)
expect(wrapper.text()).toContain('school-for-citizens')
@ -1165,6 +1197,10 @@ describe('GroupProfileSlug', () => {
expect(wrapper.find('.profile-avatar').exists()).toBe(true)
})
it('has GroupContentMenu', () => {
expect(wrapper.find('.group-content-menu').exists()).toBe(true)
})
it('has group slug', () => {
expect(wrapper.find('[data-test="at"]').exists()).toBe(true)
expect(wrapper.text()).toContain('investigative-journalism')
@ -1280,6 +1316,10 @@ describe('GroupProfileSlug', () => {
expect(wrapper.find('.profile-avatar').exists()).toBe(true)
})
it('has not(!) GroupContentMenu', () => {
expect(wrapper.find('.group-content-menu').exists()).toBe(false)
})
it('has group slug', () => {
expect(wrapper.find('[data-test="at"]').exists()).toBe(true)
expect(wrapper.text()).toContain('investigative-journalism')
@ -1395,6 +1435,10 @@ describe('GroupProfileSlug', () => {
expect(wrapper.find('.profile-avatar').exists()).toBe(false)
})
it('has not(!) GroupContentMenu', () => {
expect(wrapper.find('.group-content-menu').exists()).toBe(false)
})
it('has no(!) group slug', () => {
expect(wrapper.find('[data-test="at"]').exists()).toBe(false)
expect(wrapper.text()).not.toContain('investigative-journalism')
@ -1498,6 +1542,10 @@ describe('GroupProfileSlug', () => {
expect(wrapper.find('.profile-avatar').exists()).toBe(false)
})
it('has not(!) GroupContentMenu', () => {
expect(wrapper.find('.group-content-menu').exists()).toBe(false)
})
it('has no(!) group slug', () => {
expect(wrapper.find('[data-test="at"]').exists()).toBe(false)
expect(wrapper.text()).not.toContain('investigative-journalism')

View File

@ -16,20 +16,21 @@
</avatar-uploader>
<profile-avatar v-else :profile="group" class="profile-page-avatar" size="large" />
<!-- Menu -->
<!-- <client-only>
<content-menu
<client-only>
<group-content-menu
v-if="isGroupOwner"
class="group-content-menu"
:usage="'groupProfile'"
:group="group || {}"
placement="bottom-end"
resource-type="user"
:resource="user"
:is-owner="isGroupOwner"
class="user-content-menu"
@mute="muteUser"
/>
<!-- TODO: implement later on -->
<!-- @mute="muteUser"
@unmute="unmuteUser"
@block="blockUser"
@unblock="unblockUser"
@delete="deleteUser"
/>
</client-only> -->
@delete="deleteUser" -->
</client-only>
<ds-space margin="small">
<!-- group name -->
<ds-heading tag="h3" align="center" no-margin>
@ -313,12 +314,12 @@ import UpdateQuery from '~/components/utils/UpdateQuery'
import postListActions from '~/mixins/postListActions'
import AvatarUploader from '~/components/Uploader/AvatarUploader'
import Category from '~/components/Category'
// import ContentMenu from '~/components/ContentMenu/ContentMenu'
import ContentViewer from '~/components/Editor/ContentViewer'
import CountTo from '~/components/CountTo.vue'
import Empty from '~/components/Empty/Empty'
// import FollowButton from '~/components/Button/FollowButton'
// import FollowList from '~/components/features/ProfileList/FollowList'
import GroupContentMenu from '~/components/ContentMenu/GroupContentMenu'
import JoinLeaveButton from '~/components/Button/JoinLeaveButton'
import MasonryGrid from '~/components/MasonryGrid/MasonryGrid.vue'
import MasonryGridItem from '~/components/MasonryGrid/MasonryGridItem.vue'
@ -340,12 +341,12 @@ export default {
components: {
AvatarUploader,
Category,
// ContentMenu,
ContentViewer,
CountTo,
Empty,
// FollowButton,
// FollowList,
GroupContentMenu,
JoinLeaveButton,
PostTeaser,
ProfileAvatar,
@ -634,8 +635,8 @@ export default {
margin: auto;
margin-top: -60px;
}
.page-name-profile-id-slug {
.ds-flex-item:first-child .content-menu {
.page-name-group-id-slug {
.ds-flex-item:first-child .group-content-menu {
position: absolute;
top: $space-x-small;
right: $space-x-small;

View File

@ -22,11 +22,6 @@ export default {
required: true,
},
},
data() {
return {
GroupMembers: [],
}
},
computed: {
groupMembers() {
return this.GroupMembers ? this.GroupMembers : []