add location and location name for group

This commit is contained in:
ogerly 2022-09-15 12:38:59 +02:00
parent b57f5e253c
commit bc8cba13b3
8 changed files with 96 additions and 13 deletions

View File

@ -159,6 +159,7 @@ export const groupQuery = gql`
deleted
about
description
descriptionExcerpt
groupType
actionRadius
categories {

View File

@ -6,6 +6,7 @@ import { DESCRIPTION_WITHOUT_HTML_LENGTH_MIN } from '../../constants/groups'
import { removeHtmlTags } from '../../middleware/helpers/cleanHtml.js'
import Resolver from './helpers/Resolver'
import { mergeImage } from './images/images'
import createOrUpdateLocations from './users/location'
export default {
Query: {
@ -130,7 +131,9 @@ export default {
return group
})
try {
return await writeTxResultPromise
const group = await writeTxResultPromise
await createOrUpdateLocations(params.id, params.locationName, session)
return group
} catch (error) {
if (error.code === 'Neo.ClientError.Schema.ConstraintValidationFailed')
throw new UserInputError('Group with this slug already exists!')
@ -201,7 +204,9 @@ export default {
return group
})
try {
return await writeTxResultPromise
const group = await writeTxResultPromise
await createOrUpdateLocations(params.id, params.locationName, session)
return group
} catch (error) {
if (error.code === 'Neo.ClientError.Schema.ConstraintValidationFailed')
throw new UserInputError('Group with this slug already exists!')
@ -274,11 +279,18 @@ export default {
},
Group: {
...Resolver('Group', {
undefinedToNull: [
'deleted',
'disabled',
'locationName',
'about',
],
hasMany: {
categories: '-[:CATEGORIZED]->(related:Category)',
},
hasOne: {
avatar: '-[:AVATAR_IMAGE]->(related:Image)',
location: '-[:IS_IN]->(related:Location)',
},
}),
},

View File

@ -29,6 +29,7 @@ type Group {
about: String # goal
description: String!
descriptionExcerpt: String!
groupType: GroupType!
actionRadius: GroupActionRadius!

View File

@ -1,5 +1,6 @@
<template>
<div>
<div v-if="update">add: slug, location, tiptap editor in description</div>
<ds-container>
<ds-form
class="group-form"
@ -14,6 +15,13 @@
placeholder="Your name ..."
></ds-input>
<ds-input
v-if="update"
v-model="formData.slug"
label="Slug"
placeholder="Your name ..."
></ds-input>
<ds-select
icon="user"
v-model="formData.groupType"
@ -30,7 +38,18 @@
type="textarea"
rows="3"
></ds-input>
<ds-space margin-top="large">
<ds-select
id="city"
v-model="formData.locationName"
icon="map-marker"
:options="cities"
:label="$t('settings.data.labelCity')"
:placeholder="$t('settings.data.labelCity')"
:loading="loadingGeo"
@input.native="handleCityInput"
/>
</ds-space>
<ds-space margin-top="large">
<ds-select
icon="card"
@ -71,6 +90,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',
@ -90,24 +112,30 @@ 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,
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,
@ -127,13 +155,14 @@ export default {
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
@ -143,6 +172,43 @@ export default {
})
: this.$emit('createGroup', variables)
},
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
},
reset() {
alert('reset')
},
@ -155,6 +221,7 @@ export default {
this.formData.about !== '' &&
this.formData.description !== '' &&
this.formData.actionRadius !== '' &&
this.formData.locationName !== '' &&
this.formData.categoryIds.length > 0
) {
return false
@ -168,6 +235,7 @@ export default {
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.formData.categoryIds.length === 0 ||
!this.sameCategories
) {

View File

@ -23,7 +23,7 @@
<ds-text bold>{{ item.about }}</ds-text>
</ds-space>
<ds-space margin-top="small">
{{ item.description }}
<div v-html="item.descriptionExcerpt"></div>
</ds-space>
<ds-space margin-top="small">
<ds-chip v-for="category in item.categories" :key="category.name">
@ -34,7 +34,7 @@
</ds-space>
</ds-flex-item>
<ds-flex-item width="10%" centered>
<group-menu resource-type="group" :resource="item" :isOwner="item.myRole" @joinGroup="joinGroup"/>
<group-menu v-if="item.myRole === 'owner'" resource-type="group" :resource="item" :isOwner="item.myRole" @joinGroup="joinGroup"/>
</ds-flex-item>
</ds-flex>
</ds-card>

View File

@ -42,7 +42,7 @@ export const createGroupMutation = gql`
name
icon
}
# locationName # test this as result
locationName # test this as result
myRole
}
}
@ -170,6 +170,7 @@ export const groupQuery = gql`
deleted
about
description
descriptionExcerpt
groupType
actionRadius
categories {
@ -181,7 +182,7 @@ export const groupQuery = gql`
avatar {
url
}
# locationName # test this as result
locationName # test this as result
myRole
}
}

View File

@ -29,8 +29,8 @@ export default {
},
methods: {
async createGroup(value) {
const { name, about, description, groupType, actionRadius, categoryIds } = value
const variables = { name, about, description, groupType, actionRadius, categoryIds }
const { name, about, description, groupType, actionRadius, locationName, categoryIds } = value
const variables = { name, about, description, groupType, actionRadius, locationName, categoryIds }
try {
await this.$apollo.mutate({
mutation: createGroupMutation,

View File

@ -23,8 +23,8 @@ export default {
},
methods: {
async updateGroup(value) {
const { id, name, about, description, groupType, actionRadius, categoryIds } = value
const variables = { id, name, about, description, groupType, actionRadius, categoryIds }
const { id, name, about, description, groupType, actionRadius, locationName, categoryIds } = value
const variables = { id, name, about, description, groupType, actionRadius, locationName, categoryIds }
try {
await this.$apollo.mutate({
mutation: updateGroupMutation,