diff options
author | René Gieling <github@dartcafe.de> | 2021-06-21 09:21:09 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-21 09:21:09 +0300 |
commit | 278dabdfc9c9cb47ba497d3658bb421fc710130c (patch) | |
tree | 4199465034e70abc147ee5650bc6175df83749e6 /src | |
parent | ebb6ec15cb48fda9d0a02a68ce348a3845e6bd94 (diff) | |
parent | ae2e2da7b6738d0cc3ed862dceb7cb2a50c0e1f3 (diff) |
Merge pull request #1690 from nextcloud/fix/tablePerformance
hide vote table if too many cells are predicted
Diffstat (limited to 'src')
-rw-r--r-- | src/js/components/Actions/ActionCopyMailAdresses.vue | 4 | ||||
-rw-r--r-- | src/js/components/Poll/ParticipantsList.vue | 7 | ||||
-rw-r--r-- | src/js/components/Poll/PollInformation.vue | 6 | ||||
-rw-r--r-- | src/js/components/VoteTable/VoteTable.vue | 2 | ||||
-rw-r--r-- | src/js/store/modules/poll.js | 67 | ||||
-rw-r--r-- | src/js/store/modules/votes.js | 16 | ||||
-rw-r--r-- | src/js/views/Vote.vue | 8 |
7 files changed, 77 insertions, 33 deletions
diff --git a/src/js/components/Actions/ActionCopyMailAdresses.vue b/src/js/components/Actions/ActionCopyMailAdresses.vue index 1743f0c1..e8cc8fba 100644 --- a/src/js/components/Actions/ActionCopyMailAdresses.vue +++ b/src/js/components/Actions/ActionCopyMailAdresses.vue @@ -65,11 +65,11 @@ export default { computed: { ...mapGetters({ - participantsVoted: 'poll/participantsVoted', + countParticipantsVoted: 'poll/countParticipantsVoted', }), caption() { - return n('polls', '%n Participant', '%n Participants', this.participantsVoted.length) + return n('polls', '%n Participant', '%n Participants', this.countParticipantsVoted) }, }, methods: { diff --git a/src/js/components/Poll/ParticipantsList.vue b/src/js/components/Poll/ParticipantsList.vue index 8bbaf40d..7d5c28e5 100644 --- a/src/js/components/Poll/ParticipantsList.vue +++ b/src/js/components/Poll/ParticipantsList.vue @@ -22,13 +22,13 @@ <template lang="html"> <div class="participants-list"> - <h2 v-if="participantsVoted.length"> - {{ n('polls', '%n Participant', '%n Participants', participantsVoted.length) }} + <h2 v-if="countParticipantsVoted"> + {{ n('polls', '%n Participant', '%n Participants', countParticipantsVoted) }} </h2> <h2 v-else> {{ t('polls','No Participants until now') }} </h2> - <div v-if="participantsVoted.length" class="participants-list__list"> + <div v-if="countParticipantsVoted" class="participants-list__list"> <UserItem v-for="(participant) in participantsVoted" :key="participant.userId" v-bind="participant" @@ -61,6 +61,7 @@ export default { }), ...mapGetters({ + countParticipantsVoted: 'poll/countParticipantsVoted', participantsVoted: 'poll/participantsVoted', }), }, diff --git a/src/js/components/Poll/PollInformation.vue b/src/js/components/Poll/PollInformation.vue index 05c1d679..a9f20765 100644 --- a/src/js/components/Poll/PollInformation.vue +++ b/src/js/components/Poll/PollInformation.vue @@ -48,8 +48,8 @@ <div :class="resultsClass"> {{ resultsCaption }} </div> - <div v-if="participantsVoted.length && acl.allowSeeResults" class="icon-user"> - {{ n('polls', '%n Participant', '%n Participants', participantsVoted.length) }} + <div v-if="countParticipantsVoted && acl.allowSeeResults" class="icon-user"> + {{ n('polls', '%n Participant', '%n Participants', countParticipantsVoted) }} </div> <div class="icon-polls-unconfirmed"> {{ n('polls', '%n option', '%n options', countOptions) }} @@ -112,10 +112,10 @@ export default { }), ...mapGetters({ - participantsVoted: 'poll/participantsVoted', closed: 'poll/isClosed', confirmedOptions: 'options/confirmed', countOptions: 'options/count', + countParticipantsVoted: 'poll/countParticipantsVoted', countVotes: 'votes/countVotes', countAllVotes: 'votes/countAllVotes', proposalsAllowed: 'poll/proposalsAllowed', diff --git a/src/js/components/VoteTable/VoteTable.vue b/src/js/components/VoteTable/VoteTable.vue index 0ac5c0d4..3ca2d208 100644 --- a/src/js/components/VoteTable/VoteTable.vue +++ b/src/js/components/VoteTable/VoteTable.vue @@ -127,7 +127,7 @@ export default { ...mapGetters({ hideResults: 'poll/hideResults', closed: 'poll/isClosed', - participants: 'poll/participants', + participants: 'poll/safeParticipants', options: 'options/rankedOptions', proposalsExist: 'options/proposalsExist', }), diff --git a/src/js/store/modules/poll.js b/src/js/store/modules/poll.js index fba43db0..c89aa103 100644 --- a/src/js/store/modules/poll.js +++ b/src/js/store/modules/poll.js @@ -27,6 +27,10 @@ import { generateUrl } from '@nextcloud/router' import acl from './subModules/acl.js' import { uniqueArrayOfObjects } from '../../helpers/arrayHelper.js' +// max threshold for cells to display. If the number is too high, rendering +// of the vote table can become bad, because of too much iterations +const MAX_CELLS = 200 + const defaultPoll = () => ({ id: 0, type: 'datePoll', @@ -94,32 +98,11 @@ const getters = { }, - displayResults: (state, getters) => (state.showResults === 'always' || (state.showResults === 'closed' && !getters.closed)), - - proposalsAllowed: (state) => (state.allowProposals === 'allow' || state.allowProposals === 'review'), - - proposalsOpen: (state, getters) => getters.proposalsAllowed && !getters.proposalsExpired, - - proposalsExpired: (state, getters) => getters.proposalsAllowed && state.proposalsExpire && moment.unix(state.proposalsExpire).diff() < 0, - - proposalsExpirySet: (state, getters) => getters.proposalsAllowed && state.proposalsExpire, - - proposalsExpireRelative: (state) => moment.unix(state.proposalsExpire).fromNow(), - - proposalsOptions: () => [ - { value: 'disallow', label: t('polls', 'Disallow proposals') }, - { value: 'allow', label: t('polls', 'Allow proposals') }, - // { value: 'review', label: t('polls', 'Allow with review') }, - ], - - isClosed: (state) => (state.expire > 0 && moment.unix(state.expire).diff() < 1000), - participants: (state, getters, rootState) => { const participants = rootState.votes.list.map((item) => ({ userId: item.userId, displayName: item.displayName, isNoUser: item.isNoUser, - voted: true, })) // add current user, if not among participants and voting is allowed @@ -128,12 +111,21 @@ const getters = { userId: state.acl.userId, displayName: state.acl.displayName, isNoUser: state.isNoUser, - voted: false, }) } return uniqueArrayOfObjects(participants) + }, + safeParticipants: (state, getters) => { + if (getters.safeTable) { + return [{ + userId: state.acl.userId, + displayName: state.acl.displayName, + isNoUser: state.isNoUser, + }] + } + return getters.participants }, participantsVoted: (state, getters, rootState) => uniqueArrayOfObjects(rootState.votes.list.map((item) => ({ @@ -141,6 +133,37 @@ const getters = { displayName: item.displayName, isNoUser: item.isNoUser, }))), + + proposalsOptions: () => [ + { value: 'disallow', label: t('polls', 'Disallow proposals') }, + { value: 'allow', label: t('polls', 'Allow proposals') }, + ], + + displayResults: (state, getters) => (state.showResults === 'always' || (state.showResults === 'closed' && !getters.closed)), + + proposalsAllowed: (state) => (state.allowProposals === 'allow' || state.allowProposals === 'review'), + + proposalsOpen: (state, getters) => getters.proposalsAllowed && !getters.proposalsExpired, + + proposalsExpired: (state, getters) => getters.proposalsAllowed && state.proposalsExpire && moment.unix(state.proposalsExpire).diff() < 0, + + proposalsExpirySet: (state, getters) => getters.proposalsAllowed && state.proposalsExpire, + + proposalsExpireRelative: (state) => moment.unix(state.proposalsExpire).fromNow(), + + isClosed: (state) => (state.expire > 0 && moment.unix(state.expire).diff() < 1000), + + safeTable: (state, getters) => (getters.countCells > MAX_CELLS), + + countParticipants: (state, getters) => (getters.participants.length), + + countHiddenParticipants: (state, getters) => (getters.participants.length - getters.safeParticipants.length), + + countSafeParticipants: (state, getters) => (getters.safeParticipants.length), + + countParticipantsVoted: (state, getters) => (getters.participantsVoted.length), + + countCells: (state, getters, rootState, rootGetters) => (getters.countParticipants * rootGetters['options/count']), } const actions = { diff --git a/src/js/store/modules/votes.js b/src/js/store/modules/votes.js index 26c8bc4f..32b5efd6 100644 --- a/src/js/store/modules/votes.js +++ b/src/js/store/modules/votes.js @@ -51,9 +51,21 @@ const mutations = { && vote.voteOptionText === payload.option.pollOptionText) if (index > -1) { state.list[index] = Object.assign(state.list[index], payload.vote) - } else { - state.list.push(payload.vote) + return } + + state.list.push(payload.vote) + + // TODO: performance check for preferred strategy + // for (let i = 0; i < state.list.length; i++) { + // if (parseInt(state.list[i].pollId) === payload.pollId + // && state.list[i].userId === payload.vote.userId + // && state.list[i].voteOptionText === payload.option.pollOptionText) { + // state.list[i] = Object.assign(state.list[i], payload.vote) + // return + // } + // } + // state.list.push(payload.vote) }, } diff --git a/src/js/views/Vote.vue b/src/js/views/Vote.vue index eb903851..5d569913 100644 --- a/src/js/views/Vote.vue +++ b/src/js/views/Vote.vue @@ -52,6 +52,12 @@ </EmptyContent> </div> + <div v-if="countHiddenParticipants" class="area__footer"> + <h2> + {{ t('polls', 'Due to performance concerns {countHiddenParticipants} voters are hidden.', { countHiddenParticipants }) }} + </h2> + </div> + <div v-if="poll.anonymous" class="area__footer"> <div> {{ t('poll', 'Although participant\'s names are hidden, this is not a real anonymous poll because they are not hidden from the owner.') }} @@ -120,6 +126,8 @@ export default { pollTypeIcon: 'poll/typeIcon', viewMode: 'settings/viewMode', proposalsAllowed: 'poll/proposalsAllowed', + countHiddenParticipants: 'poll/countHiddenParticipants', + safeTable: 'poll/safeTable', }), showEmailEdit() { |