mahula 51564e5d9b
refactor(webapp): make group form's location select available as a separate component (#6245)
* WIP make location select a separate component

* trying ...

* fix update of geolocale from component

* clean up location select code

* refactor code

* refactor code

* clean up

* linting

* add first unit tests for location select

* reuse location setting component in user settings

* get it working

* fix unit test

* Update webapp/components/Select/LocationSelect.vue

Co-authored-by: Wolfgang Huß <wolle.huss@pjannto.com>

* Update webapp/components/Select/LocationSelect.spec.js

Co-authored-by: Wolfgang Huß <wolle.huss@pjannto.com>

* Update webapp/components/Select/LocationSelect.spec.js

Co-authored-by: Wolfgang Huß <wolle.huss@pjannto.com>

---------

Co-authored-by: Moriz Wahl <moriz.wahl@gmx.de>
Co-authored-by: ogerly <fridolin@tutanota.com>
Co-authored-by: Wolfgang Huß <wolle.huss@pjannto.com>
2025-05-29 16:58:36 +00:00

126 lines
3.4 KiB
Vue

<template>
<ds-form class="settings-form" v-model="formData" :schema="formSchema" @submit="submit">
<template #default="{ errors }">
<base-card>
<h2 class="title">{{ $t('settings.data.name') }}</h2>
<ds-input
id="name"
model="name"
icon="user"
:label="
$env.ASK_FOR_REAL_NAME
? $t('settings.data.realNamePlease')
: $t('settings.data.labelName')
"
:placeholder="$t('settings.data.namePlaceholder')"
/>
<ds-input id="slug" model="slug" icon="at" :label="$t('settings.data.labelSlug')" />
<location-select v-model="formData.locationName" />
<!-- eslint-enable vue/use-v-on-exact -->
<ds-input
id="about"
model="about"
type="textarea"
rows="3"
:label="$t('settings.data.labelBio')"
:placeholder="$t('settings.data.labelBio')"
/>
<base-button icon="check" :disabled="errors" type="submit" :loading="loadingData" filled>
{{ $t('actions.save') }}
</base-button>
</base-card>
</template>
</ds-form>
</template>
<script>
import { mapGetters, mapMutations } from 'vuex'
import UniqueSlugForm from '~/components/utils/UniqueSlugForm'
import LocationSelect from '~/components/Select/LocationSelect'
import { updateUserMutation } from '~/graphql/User'
import scrollToContent from './scroll-to-content.js'
export default {
mixins: [scrollToContent],
name: 'NewsFeed',
components: {
LocationSelect,
},
data() {
return {
cities: [],
loadingData: false,
loadingGeo: false,
formData: {
name: '',
slug: '',
about: '',
locationName: '',
},
}
},
mounted() {
this.formData.name = this.currentUser.name
this.formData.slug = this.currentUser.slug
this.formData.about = this.currentUser.about
this.formData.locationName = this.currentUser.locationName || ''
},
computed: {
...mapGetters({
currentUser: 'auth/user',
}),
formSchema() {
const uniqueSlugForm = UniqueSlugForm({
apollo: this.$apollo,
currentUser: this.currentUser,
translate: this.$t,
})
return {
name: { required: true, min: 3 },
...uniqueSlugForm.formSchema,
}
},
},
methods: {
...mapMutations({
setCurrentUser: 'auth/SET_USER',
}),
async submit() {
this.loadingData = true
const { name, slug, about } = this.formData
let { locationName } = this.formData || this.currentUser
locationName = locationName && (locationName.label || locationName)
try {
await this.$apollo.mutate({
mutation: updateUserMutation(),
variables: {
id: this.currentUser.id,
name,
slug,
locationName,
about,
},
update: (store, { data: { UpdateUser } }) => {
this.setCurrentUser({
...this.currentUser,
...UpdateUser,
})
},
})
this.$toast.success(this.$t('settings.data.success'))
} catch (err) {
this.$toast.error(err.message)
} finally {
this.loadingData = false
}
},
},
}
</script>
<style lang="scss">
.location-hint {
margin-top: -$space-x-small - $space-xxx-small - $space-xxx-small;
}
</style>