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/js
diff options
context:
space:
mode:
authorRené Gieling <github@dartcafe.de>2021-07-03 18:57:00 +0300
committerGitHub <noreply@github.com>2021-07-03 18:57:00 +0300
commit512a7b3ec221991a5ba42c1608e21a024655e726 (patch)
tree736366c7b227ecaaa81180a65fe83363313c67dd /src/js
parent6cf50b25898b5e7904b61b5289f9d686b4ffa9fc (diff)
parent1718b400594da0fb14af9023f38114a2e2797d41 (diff)
Merge pull request #1802 from nextcloud/performance/table-render
table rendering
Diffstat (limited to 'src/js')
-rw-r--r--src/js/App.vue6
-rw-r--r--src/js/components/Options/OptionProposals.vue2
-rw-r--r--src/js/components/Options/OptionsDate.vue1
-rw-r--r--src/js/components/Options/OptionsText.vue1
-rw-r--r--src/js/components/Poll/PollTitle.vue1
-rw-r--r--src/js/components/Settings/PerformanceSettings.vue75
-rw-r--r--src/js/components/Settings/SettingsDlg.vue6
-rw-r--r--src/js/components/SideBar/SideBar.vue5
-rw-r--r--src/js/components/VoteTable/VoteColumn.vue108
-rw-r--r--src/js/components/VoteTable/VoteTable.vue54
-rw-r--r--src/js/store/modules/poll.js6
-rw-r--r--src/js/store/modules/settings.js1
-rw-r--r--src/js/views/Administration.vue2
-rw-r--r--src/js/views/PollList.vue2
-rw-r--r--src/js/views/Vote.vue5
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',