diff options
author | René Gieling <github@dartcafe.de> | 2022-07-09 00:13:08 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-09 00:13:08 +0300 |
commit | 18c7221353c241ee19d1b2cba752d213d674e060 (patch) | |
tree | fc88f41d80e964093c1ae61f2d0beeb8f9788682 /src | |
parent | 9b152b5bd218e8b6cb2664da55eaf49522c432e6 (diff) | |
parent | e7565b3432d811b170892914dfe01d29934ee491 (diff) |
Merge pull request #2494 from nextcloud/enh/change-name
allow public users changing their name
Diffstat (limited to 'src')
-rw-r--r-- | src/js/components/User/UserMenu.vue | 77 | ||||
-rw-r--r-- | src/js/store/modules/share.js | 22 |
2 files changed, 98 insertions, 1 deletions
diff --git a/src/js/components/User/UserMenu.vue b/src/js/components/User/UserMenu.vue index 22b2d0b6..4fe89f91 100644 --- a/src/js/components/User/UserMenu.vue +++ b/src/js/components/User/UserMenu.vue @@ -32,7 +32,6 @@ <ActionInput v-if="$route.name === 'publicVote'" :class="check.status" :value="emailAddressTemp" - @click="deleteEmailAddress" @update:value="validateEmailAddress" @submit="submitEmailAddress"> <template #icon> @@ -40,6 +39,16 @@ </template> {{ t('polls', 'Edit Email Address') }} </ActionInput> + <ActionInput v-if="$route.name === 'publicVote'" + :class="checkDisplayName.status" + :value="displayNameTemp" + @update:value="validateDisplayName" + @submit="submitDisplayName"> + <template #icon> + <EditAccountIcon /> + </template> + {{ t('polls', 'Change name') }} + </ActionInput> <ActionButton v-if="$route.name === 'publicVote'" :disabled="!emailAddress" :value="emailAddress" @@ -92,6 +101,7 @@ import { generateUrl } from '@nextcloud/router' import { Actions, ActionButton, ActionCheckbox, ActionInput, ActionSeparator } from '@nextcloud/vue' import { mapState } from 'vuex' import SettingsIcon from 'vue-material-design-icons/Cog.vue' +import EditAccountIcon from 'vue-material-design-icons/AccountEdit.vue' import EditEmailIcon from 'vue-material-design-icons/EmailEditOutline.vue' import SendLinkPerEmailIcon from 'vue-material-design-icons/LinkVariant.vue' import DeleteIcon from 'vue-material-design-icons/Delete.vue' @@ -110,6 +120,7 @@ export default { ActionInput, ActionSeparator, SettingsIcon, + EditAccountIcon, EditEmailIcon, LogoutIcon, SendLinkPerEmailIcon, @@ -120,10 +131,14 @@ export default { data() { return { + displayNameTemp: '', emailAddressTemp: '', checkResult: '', checkStatus: '', checking: false, + displayNameCheckResult: '', + displayNameCheckStatus: '', + displayNameChecking: false, } }, @@ -133,6 +148,7 @@ export default { share: (state) => state.share, subscribed: (state) => state.subscription.subscribed, emailAddress: (state) => state.share.emailAddress, + displayName: (state) => state.poll.acl.displayName, }), hasCookie() { @@ -143,6 +159,10 @@ export default { return this.emailAddress === this.emailAddressTemp }, + displayNameUnchanged() { + return this.displayName === this.displayNameTemp + }, + check() { if (this.checking) { return { @@ -164,6 +184,27 @@ export default { } }, + checkDisplayName() { + if (this.displayNameChecking) { + return { + result: t('polls', 'Checking name …'), + status: 'checking', + } + } + + if (this.displayNameUnchanged) { + return { + result: '', + status: '', + } + } + + return { + result: this.displayNameCheckResult, + status: this.displayNameCheckStatus, + } + }, + personalLink() { return window.location.origin + this.$router.resolve({ @@ -177,10 +218,14 @@ export default { emailAddress() { this.emailAddressTemp = this.emailAddress }, + displayName() { + this.displayNameTemp = this.displayName + }, }, created() { this.emailAddressTemp = this.emailAddress + this.displayNameTemp = this.displayName }, methods: { @@ -223,6 +268,27 @@ export default { } }, 500), + validateDisplayName: debounce(async function(value) { + const endpoint = 'apps/polls/check/username' + + this.displayNameTemp = value + try { + this.displayNameChecking = true + await axios.post(generateUrl(endpoint), { + headers: { Accept: 'application/json' }, + userName: this.displayNameTemp, + token: this.$route.params.token, + }) + this.displayNameCheckResult = t('polls', 'valid name.') + this.displayNameCheckStatus = 'success' + } catch { + this.displayNameCheckResult = t('polls', 'Invalid email address.') + this.displayNameCheckStatus = 'error' + } finally { + this.displayNameChecking = false + } + }, 500), + async submitEmailAddress() { try { await this.$store.dispatch('share/updateEmailAddress', { emailAddress: this.emailAddressTemp }) @@ -232,6 +298,15 @@ export default { } }, + async submitDisplayName() { + try { + await this.$store.dispatch('share/updateDisplayName', { displayName: this.displayNameTemp }) + showSuccess(t('polls', 'Name changed.')) + } catch { + showError(t('polls', 'Error changing name.')) + } + }, + async resendInvitation() { try { const response = await this.$store.dispatch('share/resendInvitation') diff --git a/src/js/store/modules/share.js b/src/js/store/modules/share.js index a1c53a8d..6a4ec767 100644 --- a/src/js/store/modules/share.js +++ b/src/js/store/modules/share.js @@ -124,6 +124,28 @@ const actions = { } }, + async updateDisplayName(context, payload) { + if (context.rootState.route.name !== 'publicVote') { + return + } + + const endPoint = `apps/polls/s/${context.rootState.route.params.token}/name/${payload.displayName}` + + try { + const response = await axios.put(generateUrl(endPoint), { + headers: { Accept: 'application/json' }, + }) + context.commit('set', { share: response.data.share }) + context.dispatch('poll/get', null, { root: true }) + context.dispatch('comments/list', null, { root: true }) + context.dispatch('votes/list', null, { root: true }) + context.dispatch('options/list', null, { root: true }) + } catch (e) { + console.error('Error changing name', { error: e.response }, { payload }) + throw e + } + }, + async deleteEmailAddress(context, payload) { if (context.rootState.route.name !== 'publicVote') { return |