Sept 7 fixes (#9022)

* Fixed login incentives header

* Added achievement hover

* Removed grassy background from editing modal

* Fixed loading of other user equipment

* Prevented non admins from using habitica official

* Fixed challenge loading and leader changing on group reload

* Added community guidlines link

* Added challenge cloning

* Fixed heroes editing
This commit is contained in:
Keith Holliday
2017-09-07 13:26:53 -06:00
committed by GitHub
parent d9817be8f3
commit 3e1c128600
15 changed files with 183 additions and 76 deletions

View File

@@ -1,6 +1,6 @@
<template lang="pug">
.row
challenge-modal(:challenge='challenge', v-on:updatedChallenge='updatedChallenge')
challenge-modal(:challenge='challenge', :cloning='cloning' v-on:updatedChallenge='updatedChallenge')
close-challenge-modal(:members='members', :challengeId='challenge._id')
challenge-member-progress-modal(:memberId='progressMemberId', :challengeId='challenge._id')
@@ -68,6 +68,8 @@
button.btn.btn-danger(v-once, @click='closeChallenge()') {{$t('endChallenge')}}
div(v-if='isLeader')
button.btn.btn-secondary(v-once, @click='exportChallengeCsv()') {{$t('exportChallengeCsv')}}
div(v-if='isLeader')
button.btn.btn-secondary(v-once, @click='cloneChallenge()') {{$t('clone')}}
.description-section
h2 {{$t('challengeSummary')}}
p {{challenge.summary}}
@@ -162,11 +164,15 @@
</style>
<script>
const TASK_KEYS_TO_REMOVE = ['_id', 'completed', 'date', 'dateCompleted', 'history', 'id', 'streak', 'createdAt', 'challenge'];
import Vue from 'vue';
import bDropdown from 'bootstrap-vue/lib/components/dropdown';
import bDropdownItem from 'bootstrap-vue/lib/components/dropdown-item';
import findIndex from 'lodash/findIndex';
import cloneDeep from 'lodash/cloneDeep';
import omit from 'lodash/omit';
import uuid from 'uuid';
import { mapState } from 'client/libs/store';
import closeChallengeModal from './closeChallengeModal';
@@ -194,12 +200,14 @@ export default {
},
data () {
return {
searchId: '',
columns: ['habit', 'daily', 'todo', 'reward'],
icons: Object.freeze({
gemIcon,
memberIcon,
calendarIcon,
}),
cloning: false,
challenge: {},
members: [],
tasksByType: {
@@ -225,15 +233,69 @@ export default {
return this.user._id === this.challenge.leader._id;
},
},
async mounted () {
this.challenge = await this.$store.dispatch('challenges:getChallenge', {challengeId: this.challengeId});
this.members = await this.$store.dispatch('members:getChallengeMembers', {challengeId: this.challengeId});
let tasks = await this.$store.dispatch('tasks:getChallengeTasks', {challengeId: this.challengeId});
tasks.forEach((task) => {
this.tasksByType[task.type].push(task);
});
mounted () {
if (!this.searchId) this.searchId = this.challengeId;
if (!this.challenge._id) this.loadChallenge();
},
async beforeRouteUpdate (to, from, next) {
this.searchId = to.params.challengeId;
await this.loadChallenge();
if (this.$store.state.challengeOptions.cloning) {
this.cloneTasks(this.$store.state.challengeOptions.tasksToClone);
}
next();
},
methods: {
cleanUpTask (task) {
let cleansedTask = omit(task, TASK_KEYS_TO_REMOVE);
// Copy checklists but reset to uncomplete and assign new id
if (!cleansedTask.checklist) cleansedTask.checklist = [];
cleansedTask.checklist.forEach((item) => {
item.completed = false;
item.id = uuid();
});
if (cleansedTask.type !== 'reward') {
delete cleansedTask.value;
}
return cleansedTask;
},
cloneTasks (tasksToClone) {
let clonedTasks = [];
for (let key in tasksToClone) {
let tasksSection = tasksToClone[key];
tasksSection.forEach(task => {
let clonedTask = cloneDeep(task);
clonedTask = this.cleanUpTask(clonedTask);
clonedTask = taskDefaults(clonedTask);
this.tasksByType[task.type].push(clonedTask);
clonedTasks.push(clonedTask);
});
}
this.$store.dispatch('tasks:createChallengeTasks', {
challengeId: this.searchId,
tasks: clonedTasks,
});
},
async loadChallenge () {
this.challenge = await this.$store.dispatch('challenges:getChallenge', {challengeId: this.searchId});
this.members = await this.$store.dispatch('members:getChallengeMembers', {challengeId: this.searchId});
let tasks = await this.$store.dispatch('tasks:getChallengeTasks', {challengeId: this.searchId});
this.tasksByType = {
habit: [],
daily: [],
todo: [],
reward: [],
};
tasks.forEach((task) => {
this.tasksByType[task.type].push(task);
});
},
editTask (task) {
this.taskFormPurpose = 'edit';
this.editingTask = cloneDeep(task);
@@ -272,8 +334,8 @@ export default {
this.$root.$emit('show::modal', 'members-modal');
},
async joinChallenge () {
this.user.challenges.push(this.challengeId);
await this.$store.dispatch('challenges:joinChallenge', {challengeId: this.challengeId});
this.user.challenges.push(this.searchId);
await this.$store.dispatch('challenges:joinChallenge', {challengeId: this.searchId});
// @TODO: this doesn't work because of asyncresource
let tasks = await this.$store.dispatch('tasks:fetchUserTasks');
this.$store.state.tasks.data = tasks.data;
@@ -284,11 +346,11 @@ export default {
if (!keepChallenge) keep = 'remove-all';
let index = findIndex(this.user.challenges, (challengeId) => {
return challengeId === this.challengeId;
return challengeId === this.searchId;
});
this.user.challenges.splice(index, 1);
await this.$store.dispatch('challenges:leaveChallenge', {
challengeId: this.challengeId,
challengeId: this.searchId,
keep,
});
},
@@ -297,6 +359,7 @@ export default {
},
edit () {
// @TODO: set working challenge
this.cloning = false;
this.$root.$emit('show::modal', 'challenge-modal');
},
// @TODO: view members
@@ -309,9 +372,14 @@ export default {
},
async exportChallengeCsv () {
// let response = await this.$store.dispatch('challenges:exportChallengeCsv', {
// challengeId: this.challengeId,
// challengeId: this.searchId,
// });
window.location = `/api/v3/challenges/${this.challengeId}/export/csv`;
window.location = `/api/v3/challenges/${this.searchId}/export/csv`;
},
cloneChallenge () {
this.cloning = true;
this.$store.state.challengeOptions.tasksToClone = this.tasksByType;
this.$root.$emit('show::modal', 'challenge-modal');
},
},
};