Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/polls.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRené Gieling <github@dartcafe.de>2021-06-21 09:21:09 +0300
committerGitHub <noreply@github.com>2021-06-21 09:21:09 +0300
commit278dabdfc9c9cb47ba497d3658bb421fc710130c (patch)
tree4199465034e70abc147ee5650bc6175df83749e6 /src
parentebb6ec15cb48fda9d0a02a68ce348a3845e6bd94 (diff)
parentae2e2da7b6738d0cc3ed862dceb7cb2a50c0e1f3 (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.vue4
-rw-r--r--src/js/components/Poll/ParticipantsList.vue7
-rw-r--r--src/js/components/Poll/PollInformation.vue6
-rw-r--r--src/js/components/VoteTable/VoteTable.vue2
-rw-r--r--src/js/store/modules/poll.js67
-rw-r--r--src/js/store/modules/votes.js16
-rw-r--r--src/js/views/Vote.vue8
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() {