diff --git a/webapp/assets/_new/styles/tokens.scss b/webapp/assets/_new/styles/tokens.scss
index 6aa6410df..180f9c820 100644
--- a/webapp/assets/_new/styles/tokens.scss
+++ b/webapp/assets/_new/styles/tokens.scss
@@ -268,6 +268,7 @@ $size-avatar-large: 114px;
* @presenter Spacing
*/
+ $size-button-large: 50px;
$size-button-base: 36px;
$size-button-small: 26px;
diff --git a/webapp/components/Group/GroupCard.vue b/webapp/components/Group/GroupCard.vue
deleted file mode 100644
index 4afacaa38..000000000
--- a/webapp/components/Group/GroupCard.vue
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
-
-
- {{ item.name }}
- {{ item.categories ? item.categories.map((category) => category.name) : [] }}
- {{ item }}
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/webapp/components/Group/GroupContentMenu.vue b/webapp/components/Group/GroupContentMenu.vue
index a9a667c57..929232bfe 100644
--- a/webapp/components/Group/GroupContentMenu.vue
+++ b/webapp/components/Group/GroupContentMenu.vue
@@ -40,7 +40,13 @@ export default {
Dropdown,
},
props: {
- placement: { type: String, default: 'bottom-end' },
+ usage: {
+ type: String,
+ required: true,
+ validator: (value) => {
+ return value.match(/(groupTeaser|groupProfile)/)
+ },
+ },
resource: { type: Object, required: true },
resourceType: {
type: String,
@@ -49,6 +55,7 @@ export default {
return value.match(/(group)/)
},
},
+ placement: { type: String, default: 'bottom-end' },
},
computed: {
routes() {
diff --git a/webapp/components/Group/GroupForm.spec.js b/webapp/components/Group/GroupForm.spec.js
new file mode 100644
index 000000000..0300bacd0
--- /dev/null
+++ b/webapp/components/Group/GroupForm.spec.js
@@ -0,0 +1,39 @@
+import { config, mount } from '@vue/test-utils'
+import GroupForm from './GroupForm.vue'
+
+const localVue = global.localVue
+
+config.stubs['nuxt-link'] = ''
+
+const propsData = {
+ update: false,
+ group: {},
+}
+
+describe('GroupForm', () => {
+ let wrapper
+ let mocks
+
+ beforeEach(() => {
+ mocks = {
+ $t: jest.fn(),
+ $env: {
+ CATEGORIES_ACTIVE: true,
+ },
+ }
+ })
+
+ describe('mount', () => {
+ const Wrapper = () => {
+ return mount(GroupForm, { propsData, mocks, localVue })
+ }
+
+ beforeEach(() => {
+ wrapper = Wrapper()
+ })
+
+ it('renders', () => {
+ expect(wrapper.findAll('.group-form')).toHaveLength(1)
+ })
+ })
+})
diff --git a/webapp/components/Group/GroupForm.vue b/webapp/components/Group/GroupForm.vue
index 8a9638b1a..daf0c1d2a 100644
--- a/webapp/components/Group/GroupForm.vue
+++ b/webapp/components/Group/GroupForm.vue
@@ -1,68 +1,132 @@
-
-
+
+
+
+
+
+
+
+ {{ $t('group.type') }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('group.actionRadius') }}
+
+
+
+
+
+
+
+
+
-
- {{ formData }}
-
-
- Reset form
-
- {{ update ? $t('group.update') : $t('group.save') }}
-
-
-
-
- zurück
-
+
+
+ {{ $t('actions.cancel') }}
+
+
+ {{ update ? $t('group.update') : $t('group.save') }}
+
+
+
@@ -70,6 +134,9 @@
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 { queryLocations } from '~/graphql/location'
+
+let timeout
export default {
name: 'GroupForm',
@@ -89,24 +156,33 @@ export default {
},
},
data() {
- const { name, groupType, about, description, actionRadius, categories } = this.group
+ const { name, slug, groupType, about, description, actionRadius, locationName, categories } =
+ this.group
return {
categoriesActive: this.$env.CATEGORIES_ACTIVE,
disabled: false,
+ groupTypeOptions: ['public', 'closed', 'hidden'],
+ actionRadiusOptions: ['regional', 'national', 'continental', 'global'],
+ loadingGeo: false,
+ cities: [],
formData: {
name: name || '',
+ slug: slug || '',
groupType: groupType || '',
about: about || '',
description: description || '',
+ 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 },
+ locationName: { required: false },
categoryIds: {
type: 'array',
required: this.categoriesActive,
@@ -123,16 +199,54 @@ export default {
},
}
},
+ 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
+ )
+ },
+ submitDisableEdit() {
+ 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.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: {
submit() {
- const { name, about, description, groupType, actionRadius, categoryIds } = this.formData
+ const { name, about, description, groupType, actionRadius, locationName, categoryIds } =
+ this.formData
const variables = {
name,
about,
description,
groupType,
actionRadius,
+ locationName: locationName.label,
categoryIds,
}
this.update
@@ -142,9 +256,64 @@ export default {
})
: this.$emit('createGroup', variables)
},
- reset() {
- alert('reset')
+ changeGroupType(event) {
+ this.formData.groupType = event.target.value
+ },
+ changeActionRadius(event) {
+ this.formData.actionRadius = event.target.value
+ },
+ handleCityInput(value) {
+ clearTimeout(timeout)
+ timeout = setTimeout(() => this.requestGeoData(value), 500)
+ },
+ processLocationsResult(places) {
+ if (!places.length) {
+ return []
+ }
+ const result = []
+ places.forEach((place) => {
+ result.push({
+ label: place.place_name,
+ value: place.place_name,
+ id: place.id,
+ })
+ })
+
+ return result
+ },
+ async requestGeoData(e) {
+ const value = e.target ? e.target.value.trim() : ''
+ if (value === '') {
+ this.cities = []
+ return
+ }
+ this.loadingGeo = true
+
+ const place = encodeURIComponent(value)
+ const lang = this.$i18n.locale()
+
+ const {
+ data: { queryLocations: res },
+ } = await this.$apollo.query({ query: queryLocations(), variables: { place, lang } })
+
+ this.cities = this.processLocationsResult(res)
+ this.loadingGeo = false
},
},
}
+
+
diff --git a/webapp/components/Group/GroupList.vue b/webapp/components/Group/GroupList.vue
new file mode 100644
index 000000000..645f670d2
--- /dev/null
+++ b/webapp/components/Group/GroupList.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
diff --git a/webapp/components/Group/GroupMember.vue b/webapp/components/Group/GroupMember.vue
index f522ee795..28412d33a 100644
--- a/webapp/components/Group/GroupMember.vue
+++ b/webapp/components/Group/GroupMember.vue
@@ -1,56 +1,148 @@
- Members
-
-
-
+
+
+
+
+
-
- {{ scope.row.name }} loves {{ scope.row.loves }}
+
+
+
+ {{ scope.row.name | truncate(20) }}
+
+
-
- delete
+
+
+
+ {{ `@${scope.row.slug}` | truncate(20) }}
+
+
+
+
+
+
+ {{ $t(`group.roles.${scope.row.myRoleInGroup}`) }}
+
+
+
+
+
+
+ {{ $t('group.removeMemberButton') }}
+
+
+
+
diff --git a/webapp/components/Group/GroupTeaser.vue b/webapp/components/Group/GroupTeaser.vue
index 13836c82b..1b9ede71e 100644
--- a/webapp/components/Group/GroupTeaser.vue
+++ b/webapp/components/Group/GroupTeaser.vue
@@ -1,26 +1,183 @@
-
-
-
-
-
+
+ {{ group.name }}
+
+
+
+
+
+ {{ group.slug }}
+
+
+
+
+
+
+ {{ group && group.location ? group.location.name : '' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/webapp/components/PostTeaser/PostTeaser.vue b/webapp/components/PostTeaser/PostTeaser.vue
index 7e8471f9e..dc1829a4d 100644
--- a/webapp/components/PostTeaser/PostTeaser.vue
+++ b/webapp/components/PostTeaser/PostTeaser.vue
@@ -19,9 +19,8 @@
{{ post.title }}
-
+
-