mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-15 21:57:22 +01:00
Fix casting items on parties that exceed it limit by showing Load More Button (#13509)
* Fixed party size and notification when inviting Fixed party limit to 30 members (previously 31) and pop-up when trying to invite someone, when party has already reached it's members limit, to properly show members number. * Fixed View Party button in header Fixed View Party button in header to properly show Load More button when party size exceeds party limit. * Fixed View Party button to properly open party Fixed View Party button to properly open party members list on refreshing the main page, this bug was caused by previous commit. * Fixed SelectMembersModal to properly show Load More button Fixed SelectMembersModal (the modal that apperas when casting cards/specials on party member) to properly show Load More button when party size exceeds party limit * fix(test): limit now technically 29 plus leader * fix(test): adjust for tweakage Co-authored-by: Sabe Jones <sabrecat@gmail.com>
This commit is contained in:
@@ -7,7 +7,7 @@ import {
|
|||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
|
||||||
const INVITES_LIMIT = 100;
|
const INVITES_LIMIT = 100;
|
||||||
const PARTY_LIMIT_MEMBERS = 30;
|
const PARTY_LIMIT_MEMBERS = 29;
|
||||||
const MAX_EMAIL_INVITES_BY_USER = 200;
|
const MAX_EMAIL_INVITES_BY_USER = 200;
|
||||||
|
|
||||||
describe('Post /groups/:groupId/invite', () => {
|
describe('Post /groups/:groupId/invite', () => {
|
||||||
@@ -650,7 +650,7 @@ describe('Post /groups/:groupId/invite', () => {
|
|||||||
.to.eventually.be.rejected.and.eql({
|
.to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
message: t('partyExceedsMembersLimit', { maxMembersParty: PARTY_LIMIT_MEMBERS }),
|
message: t('partyExceedsMembersLimit', { maxMembersParty: PARTY_LIMIT_MEMBERS + 1 }),
|
||||||
});
|
});
|
||||||
}).timeout(10000);
|
}).timeout(10000);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -145,6 +145,9 @@ export default {
|
|||||||
currentWidth: 0,
|
currentWidth: 0,
|
||||||
inviteModalGroup: undefined,
|
inviteModalGroup: undefined,
|
||||||
inviteModalGroupType: undefined,
|
inviteModalGroupType: undefined,
|
||||||
|
group: {},
|
||||||
|
members: [],
|
||||||
|
membersLoaded: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -236,14 +239,26 @@ export default {
|
|||||||
this.$root.$emit('bv::show::modal', 'create-party-modal');
|
this.$root.$emit('bv::show::modal', 'create-party-modal');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async showPartyMembers () {
|
loadMembers (payload = null) {
|
||||||
const party = await this.$store.dispatch('party:getParty');
|
// Remove unnecessary data
|
||||||
|
if (payload && payload.challengeId) {
|
||||||
|
delete payload.challengeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.$store.dispatch('members:getGroupMembers', payload);
|
||||||
|
},
|
||||||
|
async showPartyMembers () {
|
||||||
|
this.group = await this.$store.dispatch('party:getParty');
|
||||||
|
this.group = this.$store.state.party.data;
|
||||||
|
this.membersLoaded = true;
|
||||||
|
this.members = this.partyMembers;
|
||||||
|
this.$store.state.memberModalOptions.loading = false;
|
||||||
this.$root.$emit('habitica:show-member-modal', {
|
this.$root.$emit('habitica:show-member-modal', {
|
||||||
groupId: party.data._id,
|
groupId: this.group._id,
|
||||||
viewingMembers: this.partyMembers,
|
group: this.group,
|
||||||
group: party.data,
|
memberCount: this.group.memberCount,
|
||||||
fetchMoreMembers: p => this.$store.dispatch('members:getGroupMembers', p),
|
viewingMembers: this.members,
|
||||||
|
fetchMoreMembers: this.loadMembers,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
setPartyMembersWidth ($event) {
|
setPartyMembersWidth ($event) {
|
||||||
|
|||||||
@@ -74,6 +74,19 @@
|
|||||||
v-if="members.length > 3"
|
v-if="members.length > 3"
|
||||||
class="row gradient"
|
class="row gradient"
|
||||||
></div>
|
></div>
|
||||||
|
<div
|
||||||
|
v-if="isLoadMoreAvailable"
|
||||||
|
class="row"
|
||||||
|
>
|
||||||
|
<div class="col-12 text-center">
|
||||||
|
<button
|
||||||
|
class="btn btn-secondary"
|
||||||
|
@click="loadMoreMembers()"
|
||||||
|
>
|
||||||
|
{{ $t('loadMore') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</b-modal>
|
</b-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -157,11 +170,13 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
MemberDetails,
|
MemberDetails,
|
||||||
},
|
},
|
||||||
props: ['group', 'hideBadge', 'item'],
|
props: ['hideBadge', 'item'],
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
sortOption: '',
|
sortOption: '',
|
||||||
members: [],
|
members: [],
|
||||||
|
group: {},
|
||||||
|
invites: [],
|
||||||
memberToRemove: '',
|
memberToRemove: '',
|
||||||
sortOptions: [
|
sortOptions: [
|
||||||
{
|
{
|
||||||
@@ -210,6 +225,14 @@ export default {
|
|||||||
|
|
||||||
return this.members;
|
return this.members;
|
||||||
},
|
},
|
||||||
|
isLoadMoreAvailable () {
|
||||||
|
// Only available if the current length of `members` is less than the
|
||||||
|
// total size of the Group/Challenge
|
||||||
|
return this.members.length < this.$store.state.memberModalOptions.memberCount;
|
||||||
|
},
|
||||||
|
challengeId () {
|
||||||
|
return this.$store.state.memberModalOptions.challengeId;
|
||||||
|
},
|
||||||
groupId () {
|
groupId () {
|
||||||
return this.$store.state.groupId || this.group._id;
|
return this.$store.state.groupId || this.group._id;
|
||||||
},
|
},
|
||||||
@@ -222,7 +245,20 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
loadMembers (payload = null) {
|
||||||
|
// Remove unnecessary data
|
||||||
|
if (payload && payload.challengeId) {
|
||||||
|
delete payload.challengeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.$store.dispatch('members:getGroupMembers', payload);
|
||||||
|
},
|
||||||
async getMembers () {
|
async getMembers () {
|
||||||
|
this.group = await this.$store.dispatch('party:getParty');
|
||||||
|
this.group = this.$store.state.party.data;
|
||||||
|
this.$store.state.memberModalOptions.memberCount = this.group.memberCount;
|
||||||
|
this.$store.state.memberModalOptions.fetchMoreMembers = this.loadMembers;
|
||||||
|
|
||||||
const { groupId } = this;
|
const { groupId } = this;
|
||||||
if (groupId && groupId !== 'challenge') {
|
if (groupId && groupId !== 'challenge') {
|
||||||
const members = await this.$store.dispatch('members:getGroupMembers', {
|
const members = await this.$store.dispatch('members:getGroupMembers', {
|
||||||
@@ -230,6 +266,11 @@ export default {
|
|||||||
includeAllPublicFields: true,
|
includeAllPublicFields: true,
|
||||||
});
|
});
|
||||||
this.members = members;
|
this.members = members;
|
||||||
|
const invites = await this.$store.dispatch('members:getGroupInvites', {
|
||||||
|
groupId,
|
||||||
|
includeAllPublicFields: true,
|
||||||
|
});
|
||||||
|
this.invites = invites;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!this.members || this.members.length === 0)
|
if ((!this.members || this.members.length === 0)
|
||||||
@@ -241,6 +282,20 @@ export default {
|
|||||||
if (!this.members || (this.members.length === 0 && !this.groupId)) {
|
if (!this.members || (this.members.length === 0 && !this.groupId)) {
|
||||||
this.members = [this.user];
|
this.members = [this.user];
|
||||||
}
|
}
|
||||||
|
this.$store.state.memberModalOptions.viewingMembers = this.members;
|
||||||
|
},
|
||||||
|
async loadMoreMembers () {
|
||||||
|
const lastMember = this.members[this.members.length - 1];
|
||||||
|
if (!lastMember) return;
|
||||||
|
|
||||||
|
const newMembers = await this.$store.state.memberModalOptions.fetchMoreMembers({
|
||||||
|
challengeId: this.challengeId,
|
||||||
|
groupId: this.groupId,
|
||||||
|
lastMemberId: lastMember._id,
|
||||||
|
includeAllPublicFields: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.members = this.members.concat(newMembers);
|
||||||
},
|
},
|
||||||
close () {
|
close () {
|
||||||
this.$root.$emit('bv::hide::modal', 'select-member-modal');
|
this.$root.$emit('bv::hide::modal', 'select-member-modal');
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export const SUPPORTED_SOCIAL_NETWORKS = [
|
|||||||
|
|
||||||
export const GUILDS_PER_PAGE = 30; // number of guilds to return per page when using pagination
|
export const GUILDS_PER_PAGE = 30; // number of guilds to return per page when using pagination
|
||||||
|
|
||||||
export const PARTY_LIMIT_MEMBERS = 30;
|
export const PARTY_LIMIT_MEMBERS = 29;
|
||||||
|
|
||||||
export const MINIMUM_PASSWORD_LENGTH = 8;
|
export const MINIMUM_PASSWORD_LENGTH = 8;
|
||||||
|
|
||||||
|
|||||||
@@ -491,7 +491,7 @@ schema.statics.validateInvitations = async function getInvitationErr (invites, r
|
|||||||
memberCount += totalInvites;
|
memberCount += totalInvites;
|
||||||
|
|
||||||
if (memberCount > shared.constants.PARTY_LIMIT_MEMBERS) {
|
if (memberCount > shared.constants.PARTY_LIMIT_MEMBERS) {
|
||||||
throw new BadRequest(res.t('partyExceedsMembersLimit', { maxMembersParty: shared.constants.PARTY_LIMIT_MEMBERS }));
|
throw new BadRequest(res.t('partyExceedsMembersLimit', { maxMembersParty: shared.constants.PARTY_LIMIT_MEMBERS + 1 }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user