From 8eb7c67f12b392ef60336eae11372bf5489f2007 Mon Sep 17 00:00:00 2001 From: Keith Holliday Date: Sat, 30 Sep 2017 23:54:12 -0500 Subject: [PATCH] Merge develop to release (#9115) * Some random quick (#9111) * Switch group button directions * Allowed admins to export challenges * Added scoping to some stable styles * Fixed challenge cloning * Tasks tags (#9112) * Added auto apply and exit * Add challenge tag editing * Fixed lint * Skill fixes (#9113) * Added local storage setting for spell drawer * Added new spell styles * Fixed typo * Reset local creds if access is denied (#9114) --- website/client/app.vue | 10 ++++ .../components/challenges/challengeDetail.vue | 6 ++- website/client/components/groups/group.vue | 11 ++-- website/client/components/groups/tavern.vue | 6 +-- .../components/inventory/stable/index.vue | 30 +++++------ website/client/components/tasks/spells.vue | 45 +++++++++++++---- website/client/components/tasks/user.vue | 50 ++++++++++++------- website/client/libs/userlocalManager.js | 23 +++++++++ website/client/store/actions/user.js | 2 +- website/client/store/index.js | 13 +++-- website/server/controllers/api-v3/user.js | 5 +- 11 files changed, 137 insertions(+), 64 deletions(-) create mode 100644 website/client/libs/userlocalManager.js diff --git a/website/client/app.vue b/website/client/app.vue index 510b69089e..8590f4ee7e 100644 --- a/website/client/app.vue +++ b/website/client/app.vue @@ -144,6 +144,16 @@ export default { return response; }, (error) => { if (error.response.status >= 400) { + // Check for conditions to reset the user auth + const invalidUserMessage = [this.$t('invalidCredentials'), 'Missing authentication headers.']; + if (invalidUserMessage.indexOf(error.response.data.message) !== -1) { + localStorage.removeItem('habit-mobile-settings'); + localStorage.removeItem('hello'); + this.$store.state.isUserLoggedIn = false; + window.location.href = '/static/home'; + return Promise.reject(error); + } + // Don't show errors from getting user details. These users have delete their account, // but their chat message still exists. let configExists = Boolean(error.response) && Boolean(error.response.config); diff --git a/website/client/components/challenges/challengeDetail.vue b/website/client/components/challenges/challengeDetail.vue index ce49b49762..53d8a7867a 100644 --- a/website/client/components/challenges/challengeDetail.vue +++ b/website/client/components/challenges/challengeDetail.vue @@ -68,7 +68,7 @@ button.btn.btn-secondary(v-once, @click='edit()') {{$t('editChallenge')}} div(v-if='isLeader') button.btn.btn-danger(v-once, @click='closeChallenge()') {{$t('endChallenge')}} - div(v-if='isLeader') + div(v-if='isLeader || isAdmin') button.btn.btn-secondary(v-once, @click='exportChallengeCsv()') {{$t('exportChallengeCsv')}} div(v-if='isLeader') button.btn.btn-secondary(v-once, @click='cloneChallenge()') {{$t('clone')}} @@ -246,6 +246,9 @@ export default { if (!this.challenge.leader) return false; return this.user._id === this.challenge.leader._id; }, + isAdmin () { + return Boolean(this.user.contributor.admin); + }, canJoin () { return !this.isMember; }, @@ -403,6 +406,7 @@ export default { cloneChallenge () { this.cloning = true; this.$store.state.challengeOptions.tasksToClone = this.tasksByType; + this.$store.state.challengeOptions.workingChallenge = Object.assign({}, this.$store.state.challengeOptions.workingChallenge, this.challenge); this.$root.$emit('show::modal', 'challenge-modal'); }, }, diff --git a/website/client/components/groups/group.vue b/website/client/components/groups/group.vue index 6f7e49eb99..8423983972 100644 --- a/website/client/components/groups/group.vue +++ b/website/client/components/groups/group.vue @@ -31,11 +31,13 @@ .row.new-message-row textarea(:placeholder="!isParty ? $t('chatPlaceholder') : $t('partyChatPlaceholder')", v-model='newMessage', @keydown='updateCarretPosition') autocomplete(:text='newMessage', v-on:select="selectedAutocomplete", :coords='coords', :chat='group.chat') - button.btn.btn-secondary.send-chat.float-left(v-once, @click='sendMessage()') {{ $t('send') }} + .row .col-6 button.btn.btn-secondary.float-left.fetch(v-once, @click='fetchRecentMessages()') {{ $t('fetchRecentMessages') }} button.btn.btn-secondary.float-left(v-once, @click='reverseChat()') {{ $t('reverseChat') }} + .col-6 + button.btn.btn-secondary.send-chat.float-right(v-once, @click='sendMessage()') {{ $t('send') }} .row.community-guidelines(v-if='!communityGuidelinesAccepted') div.col-8(v-once, v-html="$t('communityGuidelinesIntro')") @@ -301,13 +303,6 @@ .new-message-row { position: relative; } - - .send-chat { - z-index: 10; - position: absolute; - right: 1em; - bottom: 1em; - } } .toggle-up .svg-icon, .toggle-down .svg-icon { diff --git a/website/client/components/groups/tavern.vue b/website/client/components/groups/tavern.vue index 39a0d9ebca..ccfec8d7d6 100644 --- a/website/client/components/groups/tavern.vue +++ b/website/client/components/groups/tavern.vue @@ -15,10 +15,10 @@ .row .col-6 - button.btn.btn-secondary.send-chat.float-left(v-once, @click='sendMessage()') {{ $t('send') }} + button.btn.btn-secondary.float-left.fetch(v-once, @click='fetchRecentMessages()') {{ $t('fetchRecentMessages') }} + button.btn.btn-secondary.float-left(v-once, @click='reverseChat()') {{ $t('reverseChat') }} .col-6 - button.btn.btn-secondary.float-right.fetch(v-once, @click='fetchRecentMessages()') {{ $t('fetchRecentMessages') }} - button.btn.btn-secondary.float-right(v-once, @click='reverseChat()') {{ $t('reverseChat') }} + button.btn.btn-secondary.send-chat.float-right(v-once, @click='sendMessage()') {{ $t('send') }} .row.community-guidelines(v-if='!communityGuidelinesAccepted') div.col-8(v-once, v-html="$t('communityGuidelinesIntro')") diff --git a/website/client/components/inventory/stable/index.vue b/website/client/components/inventory/stable/index.vue index 1855f76e4c..875b65a13f 100644 --- a/website/client/components/inventory/stable/index.vue +++ b/website/client/components/inventory/stable/index.vue @@ -248,6 +248,22 @@ div.popover-content {{ $t('clickOnPetToFeed', {foodName: currentDraggingFood.text() }) }} + +