diff options
author | René Gieling <github@dartcafe.de> | 2021-07-03 18:57:00 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-03 18:57:00 +0300 |
commit | 512a7b3ec221991a5ba42c1608e21a024655e726 (patch) | |
tree | 736366c7b227ecaaa81180a65fe83363313c67dd /src/js | |
parent | 6cf50b25898b5e7904b61b5289f9d686b4ffa9fc (diff) | |
parent | 1718b400594da0fb14af9023f38114a2e2797d41 (diff) |
Merge pull request #1802 from nextcloud/performance/table-render
table rendering
Diffstat (limited to 'src/js')
-rw-r--r-- | src/js/App.vue | 6 | ||||
-rw-r--r-- | src/js/components/Options/OptionProposals.vue | 2 | ||||
-rw-r--r-- | src/js/components/Options/OptionsDate.vue | 1 | ||||
-rw-r--r-- | src/js/components/Options/OptionsText.vue | 1 | ||||
-rw-r--r-- | src/js/components/Poll/PollTitle.vue | 1 | ||||
-rw-r--r-- | src/js/components/Settings/PerformanceSettings.vue | 75 | ||||
-rw-r--r-- | src/js/components/Settings/SettingsDlg.vue | 6 | ||||
-rw-r--r-- | src/js/components/SideBar/SideBar.vue | 5 | ||||
-rw-r--r-- | src/js/components/VoteTable/VoteColumn.vue | 108 | ||||
-rw-r--r-- | src/js/components/VoteTable/VoteTable.vue | 54 | ||||
-rw-r--r-- | src/js/store/modules/poll.js | 6 | ||||
-rw-r--r-- | src/js/store/modules/settings.js | 1 | ||||
-rw-r--r-- | src/js/views/Administration.vue | 2 | ||||
-rw-r--r-- | src/js/views/PollList.vue | 2 | ||||
-rw-r--r-- | src/js/views/Vote.vue | 5 |
15 files changed, 201 insertions, 74 deletions
diff --git a/src/js/App.vue b/src/js/App.vue index 9929c7ae..ed501bcf 100644 --- a/src/js/App.vue +++ b/src/js/App.vue @@ -33,10 +33,7 @@ </template> <script> -// import LoadingOverlay from './components/Base/LoadingOverlay' -// import Navigation from './components/Navigation/Navigation' import SettingsDlg from './components/Settings/SettingsDlg' -// import SideBar from './components/SideBar/SideBar' import { getCurrentUser } from '@nextcloud/auth' import { showError } from '@nextcloud/dialogs' import { Content } from '@nextcloud/vue' @@ -47,9 +44,8 @@ import './assets/scss/colors.scss' import './assets/scss/hacks.scss' import './assets/scss/icons.scss' import './assets/scss/print.scss' + // TODO: remove comments, when @media:prefers-color-scheme is completely supported by core -// import './assets/scss/icons-dark.scss' -// import './assets/scss/colors-dark.scss' import './assets/scss/transitions.scss' import './assets/scss/experimental.scss' import { watchPolls } from './mixins/watchPolls' diff --git a/src/js/components/Options/OptionProposals.vue b/src/js/components/Options/OptionProposals.vue index 1afbf847..b4d2e91b 100644 --- a/src/js/components/Options/OptionProposals.vue +++ b/src/js/components/Options/OptionProposals.vue @@ -42,8 +42,6 @@ <script> import { mapState, mapGetters } from 'vuex' -// import OptionsDateAdd from './OptionsDateAdd' -// import OptionsTextAdd from './OptionsTextAdd' export default { name: 'OptionProposals', diff --git a/src/js/components/Options/OptionsDate.vue b/src/js/components/Options/OptionsDate.vue index 53ec65f7..f0999704 100644 --- a/src/js/components/Options/OptionsDate.vue +++ b/src/js/components/Options/OptionsDate.vue @@ -73,7 +73,6 @@ import moment from '@nextcloud/moment' import { Actions, ActionButton, EmptyContent, Modal } from '@nextcloud/vue' import ActionDelete from '../Actions/ActionDelete' import OptionCloneDate from './OptionCloneDate' -// import OptionsDateAdd from './OptionsDateAdd' import OptionItem from './OptionItem' import OptionItemOwner from '../Options/OptionItemOwner' import { confirmOption, removeOption } from '../../mixins/optionMixins' diff --git a/src/js/components/Options/OptionsText.vue b/src/js/components/Options/OptionsText.vue index 06fb54b9..68aecd4e 100644 --- a/src/js/components/Options/OptionsText.vue +++ b/src/js/components/Options/OptionsText.vue @@ -67,7 +67,6 @@ import draggable from 'vuedraggable' import ActionDelete from '../Actions/ActionDelete' import OptionItem from './OptionItem' import OptionItemOwner from '../Options/OptionItemOwner' -// import OptionsTextAdd from './OptionsTextAdd' import { confirmOption, removeOption } from '../../mixins/optionMixins' export default { diff --git a/src/js/components/Poll/PollTitle.vue b/src/js/components/Poll/PollTitle.vue index 74e7ddd0..47e2ba9b 100644 --- a/src/js/components/Poll/PollTitle.vue +++ b/src/js/components/Poll/PollTitle.vue @@ -32,7 +32,6 @@ <script> import { mapState, mapGetters } from 'vuex' import moment from '@nextcloud/moment' -// import Badge from '../Base/Badge' export default { name: 'PollTitle', diff --git a/src/js/components/Settings/PerformanceSettings.vue b/src/js/components/Settings/PerformanceSettings.vue new file mode 100644 index 00000000..c41a44c1 --- /dev/null +++ b/src/js/components/Settings/PerformanceSettings.vue @@ -0,0 +1,75 @@ +<!-- + - @copyright Copyright (c) 2018 René Gieling <github@dartcafe.de> + - + - @author René Gieling <github@dartcafe.de> + - + - @license GNU AGPL version 3 or any later version + - + - This program is free software: you can redistribute it and/or modify + - it under the terms of the GNU Affero General Public License as + - published by the Free Software Foundation, either version 3 of the + - License, or (at your option) any later version. + - + - This program is distributed in the hope that it will be useful, + - but WITHOUT ANY WARRANTY; without even the implied warranty of + - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + - GNU Affero General Public License for more details. + - + - You should have received a copy of the GNU Affero General Public License + - along with this program. If not, see <http://www.gnu.org/licenses/>. + - + --> + +<template> + <div> + <div class="user_settings"> + {{ t('polls', 'Limit the amount of vote cells. If the threshold is reached, all other participants get hidden to avoid performance break downs. The default value is 1000.') }} + <input v-model="threshold" + type="text" + :placeholder="t('polls', 'Enter amount of maximal allowed vote boxes.')"> + </div> + </div> +</template> + +<script> + +import { mapState } from 'vuex' + +export default { + name: 'PerformanceSettings', + + computed: { + ...mapState({ + settings: (state) => state.settings.user, + }), + + threshold: { + get() { + return this.settings.performanceThreshold + }, + set(value) { + this.writeValue({ performanceThreshold: +value }) + }, + }, + }, + + methods: { + async writeValue(value) { + await this.$store.commit('settings/setPreference', value) + this.$store.dispatch('settings/write') + }, + }, +} +</script> + +<style> + .user_settings { + padding-top: 16px; + } + + .settings_details { + padding-top: 8px; + margin-left: 26px; + } + +</style> diff --git a/src/js/components/Settings/SettingsDlg.vue b/src/js/components/Settings/SettingsDlg.vue index 309e33c7..752798a1 100644 --- a/src/js/components/Settings/SettingsDlg.vue +++ b/src/js/components/Settings/SettingsDlg.vue @@ -26,6 +26,10 @@ <FeatureSettings /> </AppSettingsSection> + <AppSettingsSection :title="t('polls', 'Performance settings')"> + <PerformanceSettings /> + </AppSettingsSection> + <AppSettingsSection :title="t('polls', 'Experimental Styles')"> <ExpertimantalSettings /> </AppSettingsSection> @@ -38,6 +42,7 @@ import { AppSettingsDialog, AppSettingsSection } from '@nextcloud/vue' import { subscribe, unsubscribe } from '@nextcloud/event-bus' import FeatureSettings from './FeatureSettings' import ExpertimantalSettings from './ExpertimantalSettings' +import PerformanceSettings from './PerformanceSettings' export default { name: 'SettingsDlg', @@ -47,6 +52,7 @@ export default { AppSettingsSection, FeatureSettings, ExpertimantalSettings, + PerformanceSettings, }, data() { diff --git a/src/js/components/SideBar/SideBar.vue b/src/js/components/SideBar/SideBar.vue index 5c4e652a..49d71747 100644 --- a/src/js/components/SideBar/SideBar.vue +++ b/src/js/components/SideBar/SideBar.vue @@ -61,11 +61,6 @@ <script> import { AppSidebar, AppSidebarTab } from '@nextcloud/vue' - -// import SideBarTabConfiguration from './SideBarTabConfiguration' -// import SideBarTabOptions from './SideBarTabOptions' -// import SideBarTabComments from './SideBarTabComments' -// import SideBarTabShare from './SideBarTabShare' import { mapState } from 'vuex' import { emit } from '@nextcloud/event-bus' diff --git a/src/js/components/VoteTable/VoteColumn.vue b/src/js/components/VoteTable/VoteColumn.vue new file mode 100644 index 00000000..b10998fe --- /dev/null +++ b/src/js/components/VoteTable/VoteColumn.vue @@ -0,0 +1,108 @@ +<!-- + - @copyright Copyright (c) 2018 René Gieling <github@dartcafe.de> + - + - @author René Gieling <github@dartcafe.de> + - + - @license GNU AGPL version 3 or any later version + - + - This program is free software: you can redistribute it and/or modify + - it under the terms of the GNU Affero General Public License as + - published by the Free Software Foundation, either version 3 of the + - License, or (at your option) any later version. + - + - This program is distributed in the hope that it will be useful, + - but WITHOUT ANY WARRANTY; without even the implied warranty of + - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + - GNU Affero General Public License for more details. + - + - You should have received a copy of the GNU Affero General Public License + - along with this program. If not, see <http://www.gnu.org/licenses/>. + - + --> + +<template lang="html"> + <div :class="['vote-column', { 'confirmed' : option.confirmed && closed }]"> + <VoteTableHeaderItem :option="option" :view-mode="viewMode" /> + + <Confirmation v-if="option.confirmed && closed" :option="option" /> + + <Counter v-else-if="acl.allowSeeResults" + :show-maybe="!!poll.allowMaybe" + :option="option" /> + <CalendarPeek v-if="poll.type === 'datePoll' && getCurrentUser() && settings.calendarPeek" :option="option" /> + + <VoteItem v-for="(participant) in participants" + :key="participant.userId" + :user-id="participant.userId" + :option="option" /> + + <OptionItemOwner v-if="proposalsExist" :option="option" class="owner" /> + + <Actions v-if="acl.allowEdit && closed" class="action confirm"> + <ActionButton v-if="closed" + :icon="option.confirmed ? 'icon-polls-confirmed' : 'icon-polls-unconfirmed'" + @click="confirmOption(option)"> + {{ option.confirmed ? t('polls', 'Unconfirm option') : t('polls', 'Confirm option') }} + </ActionButton> + </Actions> + </div> +</template> + +<script> +import { mapState, mapGetters } from 'vuex' +import { Actions, ActionButton } from '@nextcloud/vue' +import Counter from '../Options/Counter' +import VoteItem from './VoteItem' +import VoteTableHeaderItem from './VoteTableHeaderItem' +import { confirmOption } from '../../mixins/optionMixins' + +export default { + name: 'VoteColumn', + components: { + Actions, + ActionButton, + CalendarPeek: () => import('../Calendar/CalendarPeek'), + Counter, + Confirmation: () => import('../Options/Confirmation'), + VoteTableHeaderItem, + VoteItem, + OptionItemOwner: () => import('../Options/OptionItemOwner'), + }, + + mixins: [confirmOption], + + props: { + viewMode: { + type: String, + default: 'table-view', + }, + option: { + type: Object, + default: undefined, + }, + }, + + data() { + return { + modal: false, + userToRemove: '', + } + }, + + computed: { + ...mapState({ + acl: (state) => state.poll.acl, + poll: (state) => state.poll, + // share: (state) => state.share, + settings: (state) => state.settings.user, + }), + + ...mapGetters({ + closed: 'poll/isClosed', + participants: 'poll/safeParticipants', + proposalsExist: 'options/proposalsExist', + }), + + }, +} +</script> diff --git a/src/js/components/VoteTable/VoteTable.vue b/src/js/components/VoteTable/VoteTable.vue index 0e8f493d..5133df23 100644 --- a/src/js/components/VoteTable/VoteTable.vue +++ b/src/js/components/VoteTable/VoteTable.vue @@ -42,31 +42,10 @@ </div> <transition-group name="list" tag="div" class="vote-table__votes"> - <div v-for="(option) in options" :key="option.id" :class="['vote-column', { 'confirmed' : option.confirmed && closed }]"> - <VoteTableHeaderItem :option="option" :view-mode="viewMode" /> - - <Confirmation v-if="option.confirmed && closed" :option="option" /> - - <Counter v-else-if="acl.allowSeeResults" - :show-maybe="!!poll.allowMaybe" - :option="option" /> - <CalendarPeek v-if="poll.type === 'datePoll' && getCurrentUser() && settings.calendarPeek" :option="option" /> - - <VoteItem v-for="(participant) in participants" - :key="participant.userId" - :user-id="participant.userId" - :option="option" /> - - <OptionItemOwner v-if="proposalsExist" :option="option" class="owner" /> - - <Actions v-if="acl.allowEdit && closed" class="action confirm"> - <ActionButton v-if="closed" - :icon="option.confirmed ? 'icon-polls-confirmed' : 'icon-polls-unconfirmed'" - @click="confirmOption(option)"> - {{ option.confirmed ? t('polls', 'Unconfirm option') : t('polls', 'Confirm option') }} - </ActionButton> - </Actions> - </div> + <VoteColumn v-for="(item) in options" + :key="item.id" + :option="item" + :view-mode="viewMode" /> </transition-group> </div> </template> @@ -74,30 +53,16 @@ <script> import { mapState, mapGetters } from 'vuex' import { showSuccess } from '@nextcloud/dialogs' -import { Actions, ActionButton } from '@nextcloud/vue' import ActionDelete from '../Actions/ActionDelete' -// import CalendarPeek from '../Calendar/CalendarPeek' -import Counter from '../Options/Counter' -// import Confirmation from '../Options/Confirmation' -// import OptionItemOwner from '../Options/OptionItemOwner' -// import UserMenu from '../User/UserMenu' -import VoteItem from './VoteItem' -import VoteTableHeaderItem from './VoteTableHeaderItem' +import VoteColumn from './VoteColumn' import { confirmOption } from '../../mixins/optionMixins' export default { name: 'VoteTable', components: { - Actions, - ActionButton, ActionDelete, - CalendarPeek: () => import('../Calendar/CalendarPeek'), - Counter, - Confirmation: () => import('../Options/Confirmation'), UserMenu: () => import('../User/UserMenu'), - VoteTableHeaderItem, - VoteItem, - OptionItemOwner: () => import('../Options/OptionItemOwner'), + VoteColumn, }, mixins: [confirmOption], @@ -119,13 +84,12 @@ export default { computed: { ...mapState({ acl: (state) => state.poll.acl, - poll: (state) => state.poll, - share: (state) => state.share, - settings: (state) => state.settings.user, + // poll: (state) => state.poll, + // share: (state) => state.share, + // settings: (state) => state.settings.user, }), ...mapGetters({ - hideResults: 'poll/hideResults', closed: 'poll/isClosed', participants: 'poll/safeParticipants', options: 'options/rankedOptions', diff --git a/src/js/store/modules/poll.js b/src/js/store/modules/poll.js index f932f33d..b4f3a32b 100644 --- a/src/js/store/modules/poll.js +++ b/src/js/store/modules/poll.js @@ -27,10 +27,6 @@ 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', @@ -154,7 +150,7 @@ const getters = { isClosed: (state) => (state.expire > 0 && moment.unix(state.expire).diff() < 1000), - safeTable: (state, getters) => (getters.countCells > MAX_CELLS), + safeTable: (state, getters, rootState) => (getters.countCells > rootState.settings.user.performanceThreshold), countParticipants: (state, getters) => (getters.participants.length), diff --git a/src/js/store/modules/settings.js b/src/js/store/modules/settings.js index bc313fd0..041ded0f 100644 --- a/src/js/store/modules/settings.js +++ b/src/js/store/modules/settings.js @@ -34,6 +34,7 @@ const defaultSettings = () => ({ glassySidebar: false, defaultViewTextPoll: 'list-view', defaultViewDatePoll: 'table-view', + performanceThreshold: 1000, }, session: { manualViewDatePoll: '', diff --git a/src/js/views/Administration.vue b/src/js/views/Administration.vue index c7705818..8aab189f 100644 --- a/src/js/views/Administration.vue +++ b/src/js/views/Administration.vue @@ -118,8 +118,6 @@ import { showError } from '@nextcloud/dialogs' import { emit } from '@nextcloud/event-bus' import { Actions, ActionButton, AppContent, EmptyContent, Modal } from '@nextcloud/vue' import sortBy from 'lodash/sortBy' -// import LoadingOverlay from '../components/Base/LoadingOverlay' -// import PollItem from '../components/PollList/PollItem' export default { name: 'Administration', diff --git a/src/js/views/PollList.vue b/src/js/views/PollList.vue index 02f11b49..676d3637 100644 --- a/src/js/views/PollList.vue +++ b/src/js/views/PollList.vue @@ -100,8 +100,6 @@ import sortBy from 'lodash/sortBy' import { showError } from '@nextcloud/dialogs' import { emit } from '@nextcloud/event-bus' import { Actions, ActionButton, AppContent, EmptyContent } from '@nextcloud/vue' -// import PollItem from '../components/PollList/PollItem' -// import LoadingOverlay from '../components/Base/LoadingOverlay' export default { name: 'PollList', diff --git a/src/js/views/Vote.vue b/src/js/views/Vote.vue index e5d8ae38..c2070d4a 100644 --- a/src/js/views/Vote.vue +++ b/src/js/views/Vote.vue @@ -78,14 +78,9 @@ import { getCurrentUser } from '@nextcloud/auth' import { emit } from '@nextcloud/event-bus' import MarkUpDescription from '../components/Poll/MarkUpDescription' import PollTitle from '../components/Poll/PollTitle' -// import LoadingOverlay from '../components/Base/LoadingOverlay' -// import PollInformation from '../components/Poll/PollInformation' -// import PublicRegisterModal from '../components/Poll/PublicRegisterModal' -// import VoteTable from '../components/VoteTable/VoteTable' import ActionSortOptions from '../components/Actions/ActionSortOptions' import ActionChangeView from '../components/Actions/ActionChangeView' import ActionToggleSidebar from '../components/Actions/ActionToggleSidebar' -// import OptionProposals from '../components/Options/OptionProposals' export default { name: 'Vote', |