Oct 5 fixes (#9163)

* Added removing invites

* Addeed messages for empty gems to icon

* Added member for challenge members

* Fixed task cloning ending

* Fixed group task assignment

* Added small hack to prevent scrolling issues

* Fixed lint
This commit is contained in:
Keith Holliday
2017-10-05 14:41:03 -05:00
committed by GitHub
parent 3377f8a916
commit 58b033db9e
10 changed files with 95 additions and 8 deletions

View File

@@ -142,4 +142,22 @@ describe('GET /challenges/:challengeId/members', () => {
let resIds = res.concat(res2).map(member => member._id);
expect(resIds).to.eql(expectedIds.sort());
});
it('supports using req.query.search to get search members', async () => {
let group = await generateGroup(user, {type: 'party', name: generateUUID()});
let challenge = await generateChallenge(user, group);
let usersToGenerate = [];
for (let i = 0; i < 3; i++) {
usersToGenerate.push(generateUser({challenges: [challenge._id]}));
}
let generatedUsers = await Promise.all(usersToGenerate);
let profileNames = generatedUsers.map(generatedUser => generatedUser.profile.name);
let firstProfileName = profileNames[0];
let nameToSearch = firstProfileName.substring(0, 4);
let response = await user.get(`/challenges/${challenge._id}/members?search=${nameToSearch}`);
expect(response[0].profile.name).to.eql(firstProfileName);
});
});

View File

@@ -56,7 +56,8 @@
</style>
<style>
.modal {
/* @TODO: The modal-open class is not being removed. Let's try this for now */
.modal, .modal-open {
overflow-y: scroll !important;
}

View File

@@ -301,6 +301,9 @@ export default {
challengeId: this.searchId,
tasks: clonedTasks,
});
this.$store.state.challengeOptions.cloning = false;
this.$store.state.challengeOptions.tasksToClone = [];
},
async loadChallenge () {
this.challenge = await this.$store.dispatch('challenges:getChallenge', {challengeId: this.searchId});

View File

@@ -10,8 +10,13 @@ div
.col-12
strong(v-once) {{$t('selectChallengeWinnersDescription')}}
.col-12
select.form-control(v-model='winnerId')
option(v-for='member in members', :value='member._id') {{member.profile.name}}
input.form-control(type='text', v-model='searchTerm')
.col-12
div(v-for='member in memberResults', @click='selectMember(member._id)')
strong {{member.profile.name}}
span(v-if='winnerId === member._id') Selected
//- select.form-control(v-model='winnerId')
//- option(v-for='member in members', :value='member._id') {{member.profile.name}}
.col-12
button.btn.btn-primary(v-once, @click='closeChallenge') {{$t('awardWinners')}}
.col-12
@@ -72,6 +77,7 @@ div
</style>
<script>
import debounce from 'lodash/debounce';
import bModal from 'bootstrap-vue/lib/components/modal';
import bDropdown from 'bootstrap-vue/lib/components/dropdown';
import bDropdownItem from 'bootstrap-vue/lib/components/dropdown-item';
@@ -86,9 +92,25 @@ export default {
data () {
return {
winnerId: '',
searchTerm: '',
memberResults: [],
};
},
watch: {
searchTerm: debounce(function searchTerm (newSearch) {
this.searchChallengeMember(newSearch);
}, 500),
},
methods: {
async searchChallengeMember (search) {
this.memberResults = await this.$store.dispatch('members:getChallengeMembers', {
challengeId: this.challengeId,
searchTerm: search,
});
},
selectMember (memberId) {
this.winnerId = memberId;
},
async closeChallenge () {
this.challenge = await this.$store.dispatch('challenges:selectChallengeWinner', {
challengeId: this.challengeId,

View File

@@ -53,9 +53,16 @@ div
button.btn.btn-secondary(@click='loadMoreMembers()') {{ $t('loadMore') }}
.row.gradient(v-if='members.length > 3')
div(v-if='selectedPage === "invites"')
.row(v-for='member in invites')
.row(v-for='(member, index) in invites')
.col-11.no-padding-left
member-details(:member='member')
.col-1.actions
b-dropdown(right=true)
.svg-icon.inline.dots(slot='button-content', v-html="icons.dots")
b-dropdown-item(@click='removeInvite(member, index)', v-if='isLeader')
span.dropdown-icon-item
.svg-icon.inline(v-html="icons.removeIcon", v-if='isLeader')
span.text {{$t('removeInvite')}}
.modal-footer
button.btn.btn-primary(@click='close()') {{ $t('close') }}
</template>
@@ -375,6 +382,14 @@ export default {
viewInvites () {
this.selectedPage = 'invites';
},
async removeInvite (member, index) {
this.invites.splice(index, 1);
await this.$store.dispatch('members:removeMember', {
memberId: member._id,
groupId: this.groupId,
});
this.viewMembers();
},
},
};
</script>

View File

@@ -148,6 +148,7 @@
@click="itemSelected(item)"
)
span(slot="popoverContent")
strong(v-if='item.key === "gem" && gemsLeft === 0') {{ $t('maxBuyGems') }}
h4.popover-content-title {{ item.text }}
template(slot="itemBadge", scope="ctx")
@@ -156,6 +157,8 @@
:show="userItems[item.purchaseType][item.key] != 0",
:count="userItems[item.purchaseType][item.key] || 0"
)
.gems-left(v-if='item.key === "gem"')
| {{ gemsLeft }}
span.badge.badge-pill.badge-item.badge-svg(
:class="{'item-selected-badge': ctx.item.pinned, 'hide': !ctx.item.pinned}",
@@ -163,6 +166,7 @@
)
span.svg-icon.inline.icon-12.color(v-html="icons.pin")
div.fill-height
drawer(
@@ -339,6 +343,19 @@
}
}
.gems-left {
position: absolute;
right: -.5em;
top: -.5em;
color: $white;
background: $purple-200;
padding: .15em .55em;
width: 24px;
height: 24px;
border-radius: 50%;
box-shadow: 0 1px 1px 0 rgba($black, 0.12);
}
</style>
@@ -374,6 +391,7 @@
import getItemInfo from 'common/script/libs/getItemInfo';
import isPinned from 'common/script/libs/isPinned';
import shops from 'common/script/libs/shops';
import planGemLimits from 'common/script/libs/planGemLimits';
import _filter from 'lodash/filter';
import _sortBy from 'lodash/sortBy';
@@ -553,6 +571,10 @@ export default {
},
];
},
gemsLeft () {
if (!this.user.purchased.plan) return 0;
return planGemLimits.convCap + this.user.purchased.plan.consecutive.gemCapExtra - this.user.purchased.plan.gemsBought;
},
},
methods: {
getClassName (classType) {

View File

@@ -34,8 +34,6 @@
div.clearfix(slot="modal-footer")
span.balance.float-left {{ $t('yourBalance') }}
balanceInfo.float-right
</template>
<style lang="scss">

View File

@@ -767,7 +767,7 @@ export default {
await this.$store.dispatch('tasks:unassignTask', {
taskId: this.task._id,
userId: this.user._id,
userId: memberId,
});
return;
}
@@ -778,7 +778,7 @@ export default {
await this.$store.dispatch('tasks:assignTask', {
taskId: this.task._id,
userId: this.user._id,
userId: memberId,
});
},
},

View File

@@ -35,6 +35,10 @@ export async function getChallengeMembers (store, payload) {
url += `&lastId=${payload.lastMemberId}`;
}
if (payload.searchTerm) {
url += `&search=${payload.searchTerm}`;
}
let response = await axios.get(url);
return response.data.data;
}

View File

@@ -226,6 +226,10 @@ function _getMembersForItem (type) {
fields = memberFields;
addComputedStats = true;
}
if (req.query.search) {
query['profile.name'] = {$regex: req.query.search};
}
} else if (type === 'group-members') {
if (group.type === 'guild') {
query.guilds = group._id;